首先给你们看一段代码,让你们直观感觉下 Java7 和 Java8 遍历处理集合的不一样 java
Dish 是一个菜肴对象,calories 属性表示该菜品的卡路里值,name 则是菜品的名称。咱们须要过滤出卡路里小于400、而后根据卡路里值升序、接着拿到他们的名称列表并返回mysql
Java7程序员
public static List<String> getLowCaloricDishesNamesInJava7(List<Dish> dishes){ List<Dish> lowCaloricDishes = new ArrayList<>(); for(Dish d: dishes){ if(d.getCalories() < 400){ lowCaloricDishes.add(d); } } List<String> lowCaloricDishesName = new ArrayList<>(); Collections.sort(lowCaloricDishes, new Comparator<Dish>() { public int compare(Dish d1, Dish d2){ return Integer.compare(d1.getCalories(), d2.getCalories()); } }); for(Dish d: lowCaloricDishes){ lowCaloricDishesName.add(d.getName()); } return lowCaloricDishesName; }
Java8面试
public static List<String> getLowCaloricDishesNamesInJava8(List<Dish> dishes){ return dishes.stream() .filter(d -> d.getCalories() < 400) .sorted(comparing(Dish::getCalories)) .map(Dish::getName) .collect(toList()); }
若是须要多核并行处理,则只需调用 dishes.parallelStream()
便可sql
在 Java8 以前,程序员须要经过 2次遍历 + 一次集合排序才能完成的工做,Java8 只须要一个链式调用就能够解决。这就是 Stream 的强大之处后端
流是 Java API 的新成员,容许程序员以声明式的方式处理集合数据,而且支持链式调用、支持并行处理。用流处理的集合数据高效且易读。Stream 的 10 种建立方式,这篇推荐你看下。更多Java8新特性教程关注公众号Java技术栈回复Java获取。多线程
java.lang.IllegalStateException: stream has already been operated upon or closed
流已经被消费掉List<String> names = Arrays.asList("Java8", "Lambdas", "In", "Action"); Stream<String> s = names.stream(); s.forEach(System.out::println); s.forEach(System.out::println);
对流的操做能够分为两类,能够继续执行下一个流操做的称为中间操做(方法的返回值是 Stream),关闭流的操做称为终止操做。架构
除非流水线上执行终端操做,不然中间操做不会执行任何处理。流会对中间操做进行合并、短路等优化app
终端操做会从流的流水线生成结果,返回一个非 stream 的任意类型值ide
filter(Predicate<? super T> predicate)
方法能够将流中知足某条件的元素筛选出来。该方法接收一个谓词函数,返回流。好比要选出某个苹果集合中红色的苹果
List<Apple> appleList = new ArrayList<>(); List<Apple> redAppleList = appleList.stream().filter(a -> "red".equals(a.getColor())).collect(Collectors.toList());
distinct()
方法会根据元素的 hashCode() 和 equals() 方法对流中元素进行去重操做
limit(n)
方法会返回流的前 n 个元素,对于有序集合List,流会按照添加顺序返回前 n 个元素,而无序集合则不会
skip(n)
方法会跳过流的前 n 个元素,能够经过 skip(m).limit(n) 返回列表中第 m - (m+n) 区间的元素,相似与 mysql 中的 limit m,n
map(Function<? super T, ? extends R> mapper)
方法。该方法接收一个 Function 函数,对流中的每个元素使用。而后能够返回任意类型的对象。有了该方法,就能够结合 Lambda 表达式对集合中的元素使用函数进行各类转换
flatMap()
能够将流操做中多个流合并成一个流的多个元素。
举个例子:集合 words 有两个单词,如今想得到[H, e, l, o, W, r, d]
在 split 方法执行完毕后,返回的是 Stream(String[]) 对象,而此时若是执行 map 方法,返回的就是多个流的集合(这个例子中就是两个 Stream(String)),这时是没法继续接下来的 distinct 操做的,所以须要 flatMap 将两个 Stream扁平化成一个 Stream,而后进行操做
List<String> words = Arrays.asList("Hello", "World"); List<String> charList = words.stream().map(word -> word.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
该方法的方法声明 flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
中能够看出,他所使用的函数式接口 Function 第二个泛型 R 必须是 Stream流。即函数式接口的抽象方法返回值必须是 Stream流及其子类对象。
anyMatch
方法能够回答“流中是否存在至少一个复合谓词条件的元素”返回 boolean 类型的值,所以是一个终端操做,例如
List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6); if (num.stream().anyMatch(n -> n % 3 == 0)) { System.out.println("集合中有元素是3的整数倍"); }
控制台会输出'集合中有元素是3的整数倍',由于集合中 三、6都是3的整数倍,符合谓词的条件。
allMatch
方法和 anyMatch
方法原理相似,可是它仅当全部元素知足谓词条件时,返回 true。
noneMatch
与 allMatch
正好相反,仅当全部元素不知足谓词条件时,返回 true
ps:和 && || 运算符相似,以上三个操做都用到了短路的思想来提升效率。
findAny()
该方法返回当前流中的任意元素,能够和其余流操做结合使用,这里须要注意 findAny() 返回的结果被 Optional 所包裹,Optional是 Java8 为优雅的避免 NPE 所采用的新 API,这里须要说明的就是 Optional.ifPresent(Consumer<? super T> consumer) 表示当 Optional 包裹的元素不为空时,执行 consumer
num.stream().filter(n -> n > 2).findAny().ifPresent(System.out::println);
findFirst()
该方法返回当前流中的第一个元素,通常也和其余流操做(例如 filter() 过滤)结合使用。与 findAny()
不一样的是,他必定返回有序集合的第一个知足条件的元素。固然有得必有失,做为代价,findFirst()
在并行处理时限制更多一些。
reduce(T identity, BinaryOperator<T> accumulator);
方法接收两个参数:identity 初始值,accumulator 对两个数的操做。例如求集合中数字的和:
num.stream().reduce(0, (a, b) -> a + b) // 计算完成,返回 21
ps:Lambda 表达式 (a, b) -> a + b)
中 a 是上一轮执行完后的累计值,b 是本次循环流中的元素。经过累加就能够计算出数字的和。更多Java8新特性教程关注公众号Java技术栈回复Java获取。
reduce 方法不只能够求和、求积。甚至能够计算最大值、最小值。
num.stream().reduce(Integer::max); num.stream().reduce(Integer::min);
码字不易,若是你以为读完之后有收获,不妨点个推荐让更多的人看到吧!
版权申明:本文首发于博客园,做者:后青春期的Keats
地址: https://www.cnblogs.com/keats...
关注公众号Java技术栈回复"面试"获取我整理的2020最全面试题及答案。
推荐去个人博客阅读更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
以为不错,别忘了点赞+转发哦!