Stream的简单介绍和List的流操作
1、stream特点
-
stream的操作必须使用lambda作为参数
-
stream没有内部存储,只是类似水流一样从数据源抓取数据
-
对数据源进行操作但不能改变数据源,而是得到一个新的stream,并可以组成集合数组等
-
消费性,stream只能被消费一次,消费以后就失效了,如果还需要消费,则必须重新生成stream,即同一个stream对象只能使用一次
2、Stream中的部分常用方法
collect()
将流输出为特定的格式,如数组、集合等,通常结合其他方法使用,比如filter()和map()等,将这些方法返回的新的流输出为特定格式
filter()
将流通过指定的方式过滤,得到所有返回为true的元素,组成一个新的stream
List<Integer> list = new ArrayList<>(); list.add(12); list.add(18); list.add(22); list.add(30); //i类似迭代器中的迭代变量,变量名任意取,这里的意思是过滤数字大于等于18的元素,组成一个新的集合 List<Integer> result = list.stream().filter(i -> i >= 18).collect(Collectors.toList()); System.out.println("result:" + result);//result:[18, 22, 30]
map()和flatMap()
map():将一个流元素按照一定规则转换为另一个元素,适用于1对1时
//这些user都是Users的对象,里面有id和name等属性 List<Users> list = Arrays.asList(user1, user2, user3, user4); //这里的规则是拿取每个用户的name属性,这里转换成为了一个字符串,由collect方法连接成一个字符串类型的集合 List<String> names = list.stream().map(user -> user.getName()).collect(Collectors.toList()); System.out.println(names);//["张三", "李四", "王五", "赵六"]
flatMap():这里适用于1对多
//由多个Integer类型组成的集合组合而成一个大集合 List<List<Integer>> list = Arrays.asList(Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6)); //由flatMap方法将list集合中每一个元素变成流从而组成一个大的流,并由collect方法连接起来 List<Integer> result = list.stream().flatMap(i -> i.stream()).collect(Collectors.toList()); System.out.println(result);//[1, 2, 3, 4, 5, 6]
forEach()
该方法传入一个lambda表达式,遍历流的每一个元素,让每个元素都执行lambda表达式
List<Users> list = Arrays.asList(user1, user2, user3, user4); //jdk8以前: for(u : list){ if(u.getAge() >= 18){ System.out.println(u.getName()); } } //jdk8: list.stream().forEach(u -> { if(u.getAge() >= 18){ System.out.println(u.getName()); } });
reduce()
这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。也有没有起始值的情况,这时会把 Stream 的前面两个元素组合起来,返回的是 Optional。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); //求list集合的元素之和, 有起始值,result = 10 int result = liststream().reduce(0, Integer::sum); //result = 15 // 求最小值,minValue = 1 int minValue = list.stream().reduce(Double.MAX_VALUE, Double::min); // 求最大值,maxValue = 5 int maxValue = list.stream().reduce(Double.MAX_VALUE, Double::min); // 求和,sumValue = 10, 无起始值,返回Optional,所以有get()方法 sumValue = list.stream().reduce(Integer::sum).get();