1. Stream 的好处
学习一个知识点,首先都会问 what ? why ? how?
Stream是什么?为什么要用Stream ? 怎么在自己的代码中用Stream?
那么什么是流呢?Java8实战给出的定义是 :从支持数据处理操作的源生成的元素序列。
如果只看这句定义,确实云里雾里,不知其好处。可以先看看再没有Stream 之前 , 怎么来处理集合的?
// 1. 找出Pepole集合中 名称为 liyy 的People List<People> peopleList = new ArrayList<People>(); for (People people : peopleList) { if (people.getName().equalsIgnoreCase("liyy")) { System.out.println("find liyy"); break; } } // 2. 用stream 的方式找出 name = liyy 的people Optional<People> people = peopleList.stream() .filter(t->t.getName().equals("liyy")) .findFirst();
1. stream 简化了java 处理集合的繁琐 , 编码更高效
2. stream 支持函数式编程
3. stream 支持多步中间操作。如处理一个集合,filter -> map -> limit -> distinct -> collect 最终筛选得到自己想要的数据。
4. stream 不仅使处理集合更方便,且还支持并行操作集合。
2. 怎么使用Stream
Stream 是处理集合的一把好手,主要分为中间操作和终端操作。
中间操作处理完Stream 还是Stream ,但是一旦执行终端操作,就会终结Stream.得到具体的数据,可能是一个集合,也可能是其他数据。
中间操作主要有 :filter , distinct , skip , limit , map , flatmap , sorted
终端操作主要有 :allMatch , findAny , findFirst , collect , count
1. filter 用于基本的筛选
// 找出第一个名字等于liyy的People Optional<People> people = peopleList.stream() .filter(t->t.getName().equals("liyy")) .findFirst();
2. distinct 用于去重筛选的结果集
// 找出所有名字等于liyy的People并去重 List<People> peoples = peopleList.stream() .filter(t->t.getName().equals("liyy")) .distinct() .collect(Collectors.toList());
3. skip 跳过筛选,limit 截短结果集
// 找出所有名字等于liyy的People ,从第三个开始保留5个 List<People> peoples = peopleList.stream() .filter(t->t.getName().equals("liyy")) .skip(2) .limit(5) .collect(Collectors.toList());
// 4. sort 排序
// System.out.println("----升序----"); peopleList.stream() .filter(t -> "liyy".equalsIgnoreCase(t.getName())) .sorted(Comparator.comparing(People::getAge)) .forEach(t->{ System.out.println(t.getAge()); }); // System.out.println("----降序----"); peopleList.stream() .filter(t -> "liyy".equalsIgnoreCase(t.getName())) .sorted(Comparator.comparing(People::getAge).reversed()) .forEach(t->{ System.out.println(t.getAge()); });
// 5. map , flatmap
1. map :接收一个函数作为参数,并应用到集合中的每个元素上,并将其映射为一个新的元素
白话:对集合中的每个元素,运用map中的函数,得到运用函数后的结果。
2. flatmap :俗称扁平流
// 提取所有年龄
peopleList.stream()
.map(People::getAge)
.distinct()
.forEach(t->{
System.out.println("age: " + t);
});
String[] words = {"hello", "words"}; // 转变为 h e l o w r d Arrays.stream(words) .map(w->w.split("")) .forEach(t->{ System.out.println(t[0]); // h // w }); Arrays.stream(words) .forEach(t->{ System.out.println(t); // hello // word }); Arrays.stream(words) .map(w->w.split("")) .flatMap(Arrays::stream) .forEach(t->{ System.out.println(t); // h // e // l // l // o // w // o // r // d }); Arrays.stream(words) .map(w->w.split("")) .flatMap(Arrays::stream) .distinct() .forEach(t->{ System.out.println(t); // h // e // l // o // w // r // d });
// 6. Optional<T>
Optional 用于防止 NPE问题
// isPresent & get() & OrElse() Optional<People> peopleOptional = peopleList.stream() .filter(t -> t.getName().equalsIgnoreCase("liyy")) .findFirst(); if (peopleOptional.isPresent()) { System.out.println("exist liyy people"); People existPeople = peopleOptional.get(); }
// 规约 reduce
reduce : 将流中的元素反复结合,求出结果值的操作
一般用于求取最大值,最小值,总和等 ,常跟map 配合操作 成为map-reduce模式
// max int maxAge = peopleList.stream() .map(People::getAge) .reduce(Integer::max) .get(); System.out.println("max age : " + maxAge); // sum int sumAge = peopleList.stream() .map(People::getAge) .reduce(Integer::sum) .get(); System.out.println("sum age : " + maxAge);
上述总结为 工作中常用的stream操作。java8中的其他steam操作,可以用到的时候再做总结考究。