温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java引入流举例分析

发布时间:2021-11-17 09:17:49 来源:亿速云 阅读:132 作者:iii 栏目:大数据

这篇文章主要介绍“Java引入流举例分析”,在日常操作中,相信很多人在Java引入流举例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java引入流举例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. 流简介

流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,你可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理。让我们来看一个实例返回低热量(<400)的菜肴名称:

Java7版本:
List<Dish> lowCaloricDishes = new ArrayList<>();
// 用累加器筛选元素
for(Dish d: menu){
    if(d.getCalories() < 400){
        lowCaloricDishes.add(d);
    }
}
// 用匿名类对菜肴排序
Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
    public int compare(Dish d1, Dish d2){
        return Integer.compare(d1.getCalories(), d2.getCalories());
    }
});
// 处理排序后的菜名列表
List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish d: lowCaloricDishes){
    lowCaloricDishesName.add(d.getName());
}
Java8版本:
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
List<String> lowCaloricDishesName = menu.stream()
                                        .filter(d -> d.getCalories() < 400)    // 选出400卡路里以下的菜肴
                                        .sorted(comparing(Dish::getCalories))    // 按照卡路里排序
                                        .map(Dish::getName)                    // 提取菜肴名称
                                        .collect(toList());                    // 将所有的名称保存在List中
利用多核架构并行执行,只需要把stream()换成parallelStream()

Java 8中的Stream API特性:

  • 声明性——更简洁,更易读

  • 可复合——更灵活

  • 可并行——性能更好

流定义:

  • 元素序列——就像集合一样,流也提供了一个接口,可以访问特定元素类型的一组有序 值。

  • 源——流会使用一个提供数据的源,如集合、数组或输入/输出资源。 请注意,从有序集 合生成流时会保留原有的顺序。由列表生成的流,其元素顺序与列表一致。

  • 数据处理操作——流的数据处理功能支持类似于数据库的操作,以及函数式编程语言中的常用操作,如filter、map、reduce、find、match、sort等。流操作可以顺序执行,也可并行执行。

  • 流水线——很多流操作本身会返回一个流,这样多个操作就可以链接起来,形成一个大的流水线。这让我们下一章中的一些优化成为可能,如延迟和短路。流水线的操作可以看作对数据源进行数据库式查询。

  • 内部迭代——与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。

Java引入流举例分析

2. 流与集合

集合与流之间的差异就在于什么时候进行计算。集合是一个内存中的数据结构,它包含数据结构中目前所有的值——集合中的每个元素都得先算出来才能添加到集合中。相比之下,流则是在概念上固定的数据结构(你不能添加或删除元素),其元素则是按需计算的。集合和流的另一个关键区别在于它们遍历数据的方式。

2.1 只能遍历一次

和迭代器类似,流只能遍历一次。遍历完之后,我们就说这个流已经被消费掉了。以下代码会抛出一个异常,说流已被消费掉了:

List<String> title = Arrays.asList(“Java8”,”In”, “Action”);
Stream<String> s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println);

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
	at com.lujiahao.learnjava8.chapter4.StreamAndCollection.main(StreamAndCollection.java:16)

2.2 外部迭代与内部迭代

使用Collection接口需要用户去做迭代(比如用for-each),这称为外部迭代。相反,Streams库使用内部迭代

集合:用for-each循环外部迭代
List<String> names = new ArrayList<>();
for(Dish d: menu){
    names.add(d.getName());
}

集合:用背后的迭代器做外部迭代
List<String> names = new ArrayList<>();
Iterator<String> iterator = menu.iterator();
while(iterator.hasNext()) {
    Dish d = iterator.next();
    names.add(d.getName());
}

流:内部迭代
List<String> names = menu.stream()
                        .map(Dish::getName)
                        .collect(toList());

Java引入流举例分析

3. 流操作

java.util.stream.Stream中的Stream接口定义了许多操作。它们可以分为两大类。可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作。 中间操作:除非流水线上触发一个终端操作,否则中间操作不会执行任何处理。 终端操作:会从流的流水线生成结果。其结果是任何不是流的值。 Java引入流举例分析

流的使用一般包括三件事:

  • 一个数据源(如集合)来执行一个查询;

  • 一个中间操作链,形成一条流的流水线;

  • 一个终端操作,执行流水线,并能生成结果。

流的流水线背后的理念类似于构建器模式。

常见流操作: Java引入流举例分析

到此,关于“Java引入流举例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI