stream流入门
文章目录
- 前言
- 一、定义
- 二、使用
- 1.创建数据流
- 2.创建流
- 1.单列集合
- 2.数组
- 3.双列集合
- 3.中间操作
- 4.终结操作
- 三、Optional
- 1.使用
- 总结
前言
- 在工作中你会见到大量的stream流的链式编程,为了简便地操作集合和数组,同时提高效率,我们使用stream流。
一、定义
- stream流是jdk8引入的一种函数式编程的API,在Java中没有函数,所以引入新的函数式编程操作API,它是强大的处理数据的API。
二、使用
注意
我们必须要有终结操作,比如forEach(o->Println)
必须要有数据源,steam()
1.创建数据流
- .stream 创建数据流
- .distinct 去重
- .filter(each -> 条件)
- .forEach(each -> 遍历操作)
List<User> users = userServiceImpl.getAllUsers();
// 1.创建stream流
users.stream() // 创建stream流.distinct() // 去重.filter(each -> each.getAge() < 18) // 通过过滤器筛选.forEach(each -> System.out.println(each.getName())); // 遍历操作
2.创建流
1.单列集合
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.forEach(each->System.out.println(each));
2.数组
- 方法一:Arrays.stream()
int[] array = new int[]{1,2,3,4,5};
Arrays.stream(array).distinct().filter(each->each > 2).forEach(each->System.out.println(each));
- 方法二:Stream.of()
int[] array = new int[]{1,2,3,4,5};
Stream.of(array).distinct().filter(each->each > 2).forEach(each->System.out.println(each));
3.双列集合
- .entrySet() 将map转换成单列集合
- each.getKey() 获得键
- each.getValue() 获得值
Map<String, Integer> map = new HashMap<>();
map.put("迪迦",999);
map.put("戴拿",999);
map.put("盖亚",999);
map.entrySet() // 先把map变成单列集合.stream() // 再直接创造数据流.filter(o->o.getValue()>16).filter(o->o.getKey().equals("迪迦")).forEach(o->System.out.println(o)); // 终结操作
3.中间操作
- filter
- distinct
- map :将流当中的元素进行转换。注意,只能转换一层,如果说要转换成某个属性,而该属性又是一个集合,需要写两次forEach,所以我们要用flatMap。用来类型转换,常和reduce配合。
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.map(each->each.getName());.forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
- sorted:排序,如果一个类具有比较能力需要我们实现Comparable< T >接口,同时重写compareTo方法。如何确定顺序,自己去调试。
public class User implements Comparable<User>{Integer age;@Overridepublic int compareTo(User other){return this.age - other.age;}
}
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.sorted().forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
- 以上写法等价于:
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.sorted((o1,o2)->o1.getAge()-o2.getAge()).forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
- limit:设置流的长度。
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.sorted((o1,o2)->o1.getAge()-o2.getAge()).limit(2) // 取出前两个数据.forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
- skip:跳过流中的前n个元素。
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.sorted((o1,o2)->o1.getAge()-o2.getAge()).skip(2) // 跳过前两个元素.forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
- flatMap: 当需要转换成集合类型的时候,要调用两次stream。并且要使用flatMap。
List<User> users = userServiceImpl.getAllUsers();
users.stream() // 获得数据流.flatMap(each->each.getList().stream()).forEach(each->System.out.println(each)); // 将每个User对象转换为其name属性
4.终结操作
- forEach():遍历集合。
- count():统计集合中的元素。
- min()/max():统计集合中的最大最小值。
Optional<Integer> max = users.stream().flatMap(author -> author.getBooks().stream()).max((o1, o2) -> o1 - o2)
System.out.print(max.get());
- collect():用于将流中的元素累积成一个结果容器。可以通过不同的收集器Collectors来实现各种复杂的转换操作。
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users.stream().map(each->each.getAge()).collect(Collectors.toList());
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users.stream().map(each->each.getAge()).collect(Collectors.toSet());
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users.stream().filter(each->each.getAge() > 18).collect(Collectors.toMap(each->each.getId(), each->each.getName()));
- reduce:聚合操作。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
Optional<Integer> sum = list.stream().reduce((o1,o2)->o1 + o2);
- anyMatch:只要有一个匹配就返回true。
- allMatch:必须全部匹配就返回true。
- noneMatch:必须全都不匹配就返回true。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
boolean exist = list.stream().anyMatch(o1->o1 == 3);
- findAny:获取流中任意一个元素,无法保证是第一个元素。
- findFirst:获取流中的第一个元素。
List<Integer> list = Arrays.asList(1,2,3,4,5);
Optional<Integer> first = list.stream().sorted((o1,o2)->o1-o2).findFirst();
- ifPresent:判断是否存在。
first.ifPresent(o->System.out.println(o));
reduce:归并操作,将stream流中的元素进行归并操作。
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer sum = list.stream().reduce(0, (r,e)->r + e)// 表示从0开始,result+element
// 使用reduce求最小值
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer min = list.stream().reduce(0, (r, e) -> r > e ? e : r)// 表示从0开始,result+element
三、Optional
- Optional是jdk8引入的容器类,用于解决空指针问题,它表示一个值可能存在,也可能不存在,提供了一系列方法来安全出的空的情况。
- 一句话:优雅的避免空指针。
1.使用
- 创建对象,通常把它封装成一个对象来使用。
List<Users> list = userService.getAll();
Optional<List<User>> usersOptions = Optional.ofNullable(list);
userOptions.ifPresent(each->System.out.println(each));
- 安全消费值:
- 使用ifPresent()。以上就是例子。
- 安全的获取值:
- 如果 Optional 中的值为 null,则通过 Supplier 提供一个默认值。
- Supplier 是 Java 8 引入的一个函数式接口,它表示一个 提供值的供应商。
- orElseThrow:捕获,没有就抛出异常。
User user = new User("aaa","bbb");
Optional<User> userOptions = Optional.ofNullable(user);
User user = userOptions.orElseGet(()->new User("ccc","ddd"));
System.out.println(user.toString());
- 过滤器filter、转换器map、
- 跟中间操作的filter是一样的,但是它保留了结果为optional对象。
总结
- stream是一次性的。
- stream是懒加载形式的,必须要有终结方法。