《Java 8 in Action》Chapter 4:引入流
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特性:
流定义:
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()); 3. 流操作java.util.stream.Stream中的Stream接口定义了许多操作。它们可以分为两大类。可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作。 流的使用一般包括三件事:
常见流操作: 4. 小结以下是你应从本章中学到的一些关键概念。
资源获取
Tips
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |