Stream
流(stream)的操作可理解为一个数据源经过零次或多次中间操作,最后由一个终结操作完成处理,得到处理结果。
如下示例,数据源为infos, 经过中间操作filter,最后由终结操作collect生成新的List数据。
List<BizObject> list = infos.stream().filter(s -> Objects.nonNull(s.get("id"))
&& "java".equals(s.get("name"))).collect(Collectors.toList());
常用方法
anyMatch
返回boolean,可用于判断数据源中某些值是否存在;
boolean isExist = infos.stream().anyMatch(map -> Objects.nonNull(map.get("id")) && "1".equals(map.get("id")));
filter
过滤流中的元素,保留满足条件的元素;sorted
对流中数据元素进行排序;findAny
查找数据源中的元素并返回;
Optional<Object> obj = = infos.stream().filter(s -> Objects.nonNull(s.get("id"))).findAny().orElse(null);
Object a = infos.stream().filter(s -> Objects.nonNull(s.get("id"))).findAny().get();
Optional<Map<String, Object>> idOpt = infos.stream().filter(map -> Objects.nonNull(map.get("id")) && "1".equals(map.get("id"))).findAny();
idOpt.isPresent();
findAny()一般与orElse()一起使用,orElse会在找不到元素时设置默认值,不至于导致报空指针异常;
forEach
无序循环地对流中的元素进行处理;
infos.forEach(info-> {info.put("id",10)});
note:
在forEach中定义变量并对变量进行操作时,会报错Variable used in lambda expression should be final or effectively final, 这是因为Lambda 表达式其实是匿名内部类,匿名类中如果要访问局部变量的话,那个局部变量必须显式的声明为 final。解决此报错,可将forEach改为for:loop的方式。
map
用于把每个元素映射到对应结果里;
List<Integer> squareNums = nums.stream().map(i -> i * i). collect(Collectors.toList());
reduce
对stream中元素进行聚合求值;
Optional reduce(BinaryOperator accumulator);
对stream中的元素通过累加器accumulator迭代计算;
T reduce(T identity, BinaryOperator accumulator);
给定一个初始值identity,再通过累加器accumulator迭代计算。
List<Integer> list = Arrays.asList(1, 2, 3, 4);
int sum = list.stream().reduce(Integer::sum).get();
System.out.println(sum); // 10
int identitySum = list.stream().reduce(sum, Integer::sum);
System.out.println(identitySum); // 20
collect
将数据源生成新的数据结构;
双冒号::
java8中可以使用::去引用方法,class::method。
ArrayList<String> list= infos.stream().map(String::toUpperCase).collect(Collectors.toCollection(ArrayList::new));
上述代码用lambda表达式写的话,如下:
List<String> list= infos.stream().map(i -> i.toUpperCase()).collect(Collectors.toList());