Stream:流
Collectors:收集器,将元素放进一个集合、分组、汇总等
forEach、collect、limit :终端操作
parallelStream:并行处理
Stream
filter():过滤出true的行
map():给定返回元素
mapToInt():给定返回元素是int类型
mapToLong():同上
mapToDouble():同上
flatMap():多个stream合并为一个stream,多用于嵌套的数据结构
flatMapToInt():
flatMapToLong():
flatMapToDouble():
distinct():去重
sorted():排序
sorted(Comparator<? super T> comparator):指定排序
peek():对流中的每个元素执行一个操作,可修改属性值,但是必须有终结操作才生效
limit(long maxSize):截取长度
skip(long n):跳过n个元素
forEach():遍历集合,在并行流中不能保持顺序
forEachOrdered():遍历集合,在并行流中也能保持顺序
toArray():转换集合
reduce(一个入参):做累加、累减,求取最大值、最小值
reduce(两个入参):另一个参数是初始值,放入计算
reduce(三个入参):第三个值在并行流生效
collect():把stream规约成一个value的规约操作,这里的value可以是一个Collection、Map或者一个value对象
min():取最小值
max():取最大值
count():计数
anyMatch():判断的条件里,任意一个元素符合条件,就返回true值
allMatch():判断的条件里,全部元素符合条件,就返回true
noneMatch():判断的条件里的元素,所有的元素都不符合,就返回true
findFirst():返回Stream中的第一个元素
findAny():返回Stream中的任何元素
builder():stream构造器
empty():通过Stream.empty()创建空流
of():Stream.of创建流
iterate():创建一个无限流,可配合limit使用,java9新加参数,可以条件判断停止生成
concat():将两个Stream对象合为一个Stream
Collector
toCollection():获取一个可修改的(增删) List 集合,如 Collectors.toCollection(ArrayList::new)
toList():将流中的元素收集到一个List集合
toSet():将流中的元素收集到一个Set集合
joining():通过分隔符、前缀、后缀等合并字符串
mapMerger()
mapping():操作后聚合,自定义映射结果
collectingAndThen():操作链,先对集合进行一次聚合操作,然后通过Function定义的函数,对聚合后的结果再次处理
counting():分组后记数
minBy()/maxBy():指定比较器中的最大/最小元素,需要参数Comparator
summingInt() /summingLong() /summingDouble():求和
sumWithCompensation
computeFinalSum
averagingInt
averagingLong
averagingDouble
reducing():聚合后操作
groupingBy():分组
partitioningBy():分组,与groupingBy的区别在于,partitioningBy借助Predicate断言,可以将集合元素分为true和false两部分
groupingByConcurrent():和groupingBy() 方法类似,区别是线程安全
toMap
toConcurrentMap():并发Map,用法和toMap()类似
summarizingInt /summarizingLong /summarizingDouble
toList / toMap / toSet
//list过滤并返回指定元素的list
List<String> rstList = list.stream().filter(p -> StringUtils.isNotBlank(p.getAge())).map(Person::getId).collect(Collectors.toList());
//同上,转换成Set,会过滤掉重复项,同.distinct()
Set<String> set = list.stream().map(Person::getName).collect(Collectors.toSet());
//list转map的几种写法
//指定key,返回entity
Map<String, Person> map = list.stream().collect(Collectors.toMap(Person::getName, Function.identity()));
//指定key,返回entity
Map map = list.stream().collect(Collectors.toMap(k->k.getName()+k.getCode(),Function.identity()));
//指定key,返回entity,并指定重复key处理方式,不加情况出现重复key报错
list.stream().collect(Collectors.toMap(Person::getId, Function.identity(), (a, b) -> a));
//转为map,获取重复key中指定元素最大的
Map<Integer, Person> map = people.stream().collect(Collectors.toMap(Person::getAge, Function.identity(), BinaryOperator.maxBy(Comparator.comparing(Person::getWeight))));
//map过滤成新的map,某些toMap使用中,当value为空时,会空指针,使用以下两种方式可以避免
dataMap.entrySet().stream().map(vo -> {
return Pair.of(vo.getKey(), vo.getValue());
}).collect(HashMap::new, (m, o) -> m.put(o.getKey(), o.getValue()), HashMap::putAll);
dataMap.entrySet().stream().map(vo -> {
return Pair.of(vo.getKey(), vo.getValue());
}).collect(Map.Entry::getKey, Optional.ofNullable(Map.Entry::getValue).orElse(-1), (v1, v2) -> v1);//给默认值
//指定元素分组,通过joining组合指定值并返回
Map<String, String> map = list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.joining(","))));
//对map的key或value进行处理,如value Double转Bigdecimal
Map<String, BigDecimal> transMap = mapData.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> BigDecimal.valueOf(entry.getValue())));
groupingBy
//简单分组
list.stream().collect(Collectors.groupingBy(Person::getAge);
//分组并归集为set集合
list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.toSet());
//分组并获取第一个值
list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.collectingAndThen(Collectors.toList(), list -> list.get(0))));
//分组计数
list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
// 将员工先按年龄分组,再按工资分组
Map<Integer, Map<String, List<Person>>> group = list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(Person::getSalary)));
partitioningBy
//返回结果是,{ true = [], false = [] }
list.stream().collect(Collectors.partitioningBy(p -> p.getAge() > 22));
//去重
list.stream().collect(Collectors.partitioningBy(p -> p.getAge() > 22, Collectors.toSet()));
mapping
Map<String, List<String>> groupMapping = students.stream()
.collect(Collectors.groupingBy(Student::getCourse, Collectors.mapping(Student::getName, Collectors.toList())));
Map<String, List<NewStudent>> groupMapping2 = students.stream()
.filter(s -> s.getScore() > 60)
.collect(Collectors.groupingBy(Student::getCourse, Collectors.mapping(s -> BeanUtil.copyProperties(s, NewStudent.class), Collectors.toList())));
// 组合joining
Map<String, String> groupMapperThenJoin= students.stream()
.collect(Collectors.groupingBy(Student::getCourse, Collectors.mapping(Student::getName, Collectors.joining(","))));
// 利用collectingAndThen处理joining后的结果
Map<String, String> groupMapperThenLink = students.stream()
.collect(Collectors.groupingBy(Student::getCourse,
Collectors.collectingAndThen(Collectors.mapping(Student::getName, Collectors.joining(",")), s -> "学生名单:" + s)));
collectingAndThen
//分组 - 归集 - 获取每组排序第一的元素
Map<String, Entity> map = list.stream().collect(Collectors.groupingBy(item -> item.getId()+"_"+item.getCode(), Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
//分组 - 归集 - 指定映射字段求和
dataList.stream().collect(Collectors.groupingBy(vo -> vo.getCode(), Collectors.collectingAndThen(
Collectors.toList(), list -> list.stream().map(vo -> vo.getAmount()).reduce(ArithUtil::add).orElse(0d)
)));
//归集 - 去重/排序 (姿势一)
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(People::getCode))), ArrayList::new));
//归集 - 去重/排序(姿势二)
list = list.stream().collect(Collectors.toList(), list -> list.stream().distinct().sorted(Comparator.comparing(People::getCode)).collect(Collectors.toList())));
reducing
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
//求和姿势一
Optional<Integer> sum = numbers.stream().collect(Collectors.reducing((x, y) -> x + y));
//求和姿势二
int sum = numbers.stream().collect(Collectors.reducing(0, Integer::sum));
//求和姿势三
list.stream().collect(Collectors.reducing(0.0, Person::getWeight, Double::sum));
//查找最大值
Optional<Integer> max = numbers.stream().collect(Collectors.reducing(Integer::max));
其他
//0.准备两个个数组
Integer[] ints1 = {1,2,3};
Integer[] ints2 = {10,20,30};
//1.生成两个流
Stream<Integer> stream1 = Stream.of(ints1);
Stream<Integer> stream2 = Stream.of(ints2);
//2.合并两个流并进行输出
Stream.concat(stream1,stream2).forEach(System.out::println);
//生成随机数
Stream.generate(() -> new Random().nextInt(20) + 1).limit(5).collect(Collectors.toList());
//排序
// 先按工资再按年龄升序排序
List<String> = list.stream()
.sorted(Comparator.comparing(Person::getAccount).thenComparing(Person::getAge))
.map(Person::getName)
.collect(Collectors.toList());
//倒序排序,并将null放在最后(reversed() 倒序):大->小->null
//naturalOrder()表示自然排序(一般是升序),数字的自然顺序是数字顺序,字符串按字母顺序排序,日期按时间顺序排序。
//reverseOrder()表示 降序。
List<String> = list.stream()
.sorted(Comparator.comparing(Person::getAge, Comparator.nullsLast(Comparator.naturalOrder())).reversed())
.map(Person::getName)
.collect(Collectors.toList());
//list组合成字符串
String names = list.stream().map(person -> person.getName()).collect(Collectors.joining("-"));