lambada表达式 -03
Java8函数式编程(三):Collectors.groupingBy
先祭出VO:
@Getter
@Setter
@ToString
class Fruit {
private String name;
private Double price;
public Fruit(String name, Double price) {
this.name = name;
this.price = price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Fruit fruit = (Fruit) o;
return java.util.Objects.equals(name, fruit.name) &&
java.util.Objects.equals(price, fruit.price);
}
@Override
public int hashCode() {
return java.util.Objects.hash(name, price);
}
// 注意equals和hashCode必须成对出现
}
1)计数
List<Fruit> fruitList = Lists.newArrayList(new Fruit("apple", 6),
new Fruit("apple", 6),
new Fruit("banana", 7), new Fruit("banana", 7),
new Fruit("banana", 7), new Fruit("grape",8));
Map<String, Long> map = fruitList.stream().
collect(Collectors.groupingBy(Fruit::getName,Collectors.counting()));
输出结果是:{banana=3, apple=2, grape=1}
换一种啰嗦、复杂的写法,但能加深理解。
Map<String, Long> map = fruitList.stream().map(Fruit::getName).
collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
2)排序
现在要按照水果map中value的数量逆序打印每个entry
map.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.forEachOrdered(System.out::println);
3)累加求和
Map<String, Integer> sumMap = fruitList.stream().collect.
(Collectors.groupingBy(Fruit::getName, Collectors.summingInt(Fruit::getPrice)));
输出结果是:{banana=21, apple=12, grape=8}
4)分组
Map<String, List<Fruit>> groupMap =
fruitList.stream().collect(Collectors.groupingBy(Fruit::getName));
上述代码根据name将list分组,如果name是唯一的,那么上述代码就会显得啰嗦。我们需要知道,Guava补JDK之不足,现在改Guava一显身手了。
Map<String, Fruit> map = Maps.uniqueIndex(fruitList, Fruit::getName);
生成的Map是ImmutableMap,不可更改里面的值。比如map.remove(“apple”)会抛出异常:java.lang.UnsupportedOperationException
根据不同的名字分为若干组
// group by price, uses 'mapping' to convert List<Fruit> to List<String>
Map<String, List<Integer>> groupMap =
fruitList.stream().collect(Collectors.groupingBy(Fruit::getName,
Collectors.mapping(Fruit::getPrice, Collectors.toList())));
上面一段代码可以用Guava代替
Multimap<String, Integer> multiMap = ArrayListMultimap.create();
fruitList.forEach(fruit -> multiMap.put(fruit.getName(), fruit.getPrice()));
可以看到有三个参数,第一个参数就是key的Function了,第二个参数是一个map工厂,也就是最终结果的容器,一般默认的是采用的HashMap::new,最后一个参数很重要是一个downstream,类型是Collector,也是一个收集器,那就是说,这三个参数其实就是为了解决分组问题的
第一个参数:分组按照什么分类
第二个参数:分组最后用什么容器保存返回
第三个参数:按照第一个参数分类后,对应的分类的结果如何收集
其实一个参数的Collectors.groupingBy方法的 ,第二个参数默认是HashMap::new, 第三个参数收集器其实默认是Collectors.toList
所以HashMap是无序的大家都是知道的,所以原因找到了。
Map<LocalDate, List<Model>> modelMap = modelVOList.stream().collect(Collectors.groupingBy(Model::getGroupTime, LinkedHashMap::new, Collectors.toList()))
本文来自博客园,作者:Jerry&Ming,转载请注明原文链接:https://www.cnblogs.com/jerry-ming/p/16571272.html