先早点数据
pigs.add(new Pig(1, "猪爸爸", 31, "M", false)); pigs.add(new Pig(2, "猪妈妈", 28, "F", true)); pigs.add(new Pig(3, "乔治", 2, "M", false)); pigs.add(new Pig(4, "佩奇", 5, "F", false)); pigs.add(new Pig(5, null, 1, "F", false));
List<Integer> idList = pigs.stream() .map(Pig::getId) .collect(Collectors.toList());
Set<String> genderSet = pigs.stream() .map(Pig::getGender) .collect(Collectors.toSet());
Map<Integer, String> idNameMap = pigs.stream() .collect( Collectors.toMap( Pig::getId, Pig::getName ) );
因为id=5的name是null,所以报错NullPointerException。
通过下面判断name是否为null,来解决该问题
Map<Integer, String> idNameMap = pigs.stream() .collect( Collectors.toMap( Pig::getId, pig -> pig.getName() == null ? "" : pig.getName() ) );
如果key重复,会报异常,这个时候得指定重复用哪一个,得加上(oldValue, newValue) -> newValue)
Map<String, String> genderNameMap = pigs.stream() .collect( Collectors.toMap( Pig::getGender, pig -> pig.getName() == null ? "" : pig.getName(), (oldValue, newValue) -> newValue) );
Optional<Pig> maxAgePig = pigs.stream() .filter(a -> a.getAge() != null) .collect( Collectors.maxBy( Comparator.comparing(Pig::getAge) ) );
Double avgAge = pigs.stream() .filter(a -> a.getAge() != null) .collect( Collectors.averagingInt(Pig::getAge) );
Integer sumAge = pigs.stream() .collect( Collectors.summingInt(Pig::getAge) );
IntSummaryStatistics statisticsAge = pigs.stream() .collect( Collectors.summarizingInt(Pig::getAge) ); System.out.println("sumAge = " + statisticsAge);
结果如下:
sumAge = IntSummaryStatistics{count=5, sum=67, min=1, average=13.400000, max=31}
String ids = pigs.stream() .map(a -> String.valueOf(a.getId())) .collect(Collectors.joining(",")); System.out.println("ids = " + ids);
结果如下:
ids = 1,2,3,4,5
根据Gender分组
//一级分组 Map<String, List<Pig>> groupByGender = pigs.stream() .collect( Collectors.groupingBy(Pig::getGender) );
结果如下:
F -> [Pig(id=2, name=猪妈妈, age=28, gender=F, valid=true), Pig(id=4, name=佩奇, age=5, gender=F, valid=false), Pig(id=5, name=null, age=1, gender=F, valid=false)] M -> [Pig(id=1, name=猪爸爸, age=31, gender=M, valid=false), Pig(id=3, name=乔治, age=2, gender=M, valid=false)]
统计每个性别的个数
Map<String, Long> groupByGenderThenCount = pigs.stream() .collect( Collectors.groupingBy( Pig::getGender, Collectors.counting() ) );
结果如下:
F -> 3 M -> 2
按照性别分组后,再求各自中年级最小的
Map<String, Pig> groupByGenderThenMinAge = pigs.stream() .collect( Collectors.groupingBy( Pig::getGender, Collectors.collectingAndThen( Collectors.minBy( Comparator.comparingInt(Pig::getAge) ), Optional::get ) ) );
先gender分组,后valid分组
Map<String, Map<Boolean, List<Pig>>> groupByGenderAndValid = pigs.stream() .collect( Collectors.groupingBy( Pig::getGender, Collectors.groupingBy(Pig::isValid) ) );
结果如下:
F -> {false=[Pig(id=4, name=佩奇, age=5, gender=F, valid=false), Pig(id=5, name=null, age=1, gender=F, valid=false)], true=[Pig(id=2, name=猪妈妈, age=28, gender=F, valid=true)]} M -> {false=[Pig(id=1, name=猪爸爸, age=31, gender=M, valid=false), Pig(id=3, name=乔治, age=2, gender=M, valid=false)]}
Map<Boolean, List<Pig>> partByAge = pigs.stream() .collect( Collectors.partitioningBy(a -> a.getAge() > 20) );
结果如下:
false -> [Pig(id=3, name=乔治, age=2, gender=M, valid=false), Pig(id=4, name=佩奇, age=5, gender=F, valid=false), Pig(id=5, name=null, age=1, gender=F, valid=false)] true -> [Pig(id=1, name=猪爸爸, age=31, gender=M, valid=false), Pig(id=2, name=猪妈妈, age=28, gender=F, valid=true)]
Map<Boolean, Long> partByAgeThenCount = pigs.stream() .collect( Collectors.partitioningBy( a -> a.getAge() > 20, Collectors.counting() ) );
结果如下:
false -> 3 true -> 2