是Java8收集器中的一种,与SQL的GROUP BY子句类似的功能。
1.1,分组
// 根据unitcode进行分组,将unitcode相同的CbhsHsunitInfEntity实体放入list中,
// 此时key是unitcode,value是list
Map<String, List<CbhsHsunitInfEntity>> unitMap = commonApiDao.getScrollData(CbhsHsunitInfEntity.class).getResultlist().stream().collect(Collectors.groupingBy(CbhsHsunitInfEntity::getUnitcode));
}));
1.2,计数
// 根据unitcode进行分组,将unitcode相同的CbhsHsunitInfEntity实体放入list中,
// 此时key是unitcode,value是list.size()
Map<String, List<CbhsHsunitInfEntity>> unitMap = commonApiDao.getScrollData(CbhsHsunitInfEntity.class).getResultlist().stream().collect(Collectors.groupingBy(CbhsHsunitInfEntity::getUnitcode,Collectors.counting()));
参考链接:java8 特性 - groupingBy
1.3,累和
// 根据unitcode进行分组,将unitcode相同的CbhsHsunitInfEntity实体放入list中,
// 此时key是unitcode,value是list中每个price的累和
Map<String, List<CbhsHsunitInfEntity>> unitMap = commonApiDao.getScrollData(CbhsHsunitInfEntity.class).getResultlist().stream().collect(Collectors.groupingBy(CbhsHsunitInfEntity::getUnitcode,Collectors.summingInt(CbhsHsunitInfEntity::getPrice)));
1.4,排序并打印数据
// 现在要按照map中value的数量逆序打印每个entry
Map<String, Long> map = fruitList.stream().map(Fruit::getName).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
map.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.forEachOrdered(System.out::println);
参考链接:Java8函数式编程(三):Collectors.groupingBy
2.1 将list转换为map,并设置key,value
部分源码:
public static <T, K, U> Collector<T, ?, Map<K,U>>
toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M>
toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
这是一个将List
// 输出一个map类型的数据,其中,unitcode为key值,levelcode2为value值
String sqlks1 = "select distinct levelcode2,b.unitcode from sys_info a,sys_info_unitmap b where a.code=b.kscode ";
Map<String, String> unitKsMap = jdbcTemplate.queryForList(sqlks1).stream().collect(Collectors.toMap(new Function<Map<String, Object>, String>()
{
@Override
public String apply(Map<String, Object> stringObjectMap) {
return stringObjectMap.get("unitcode").toString();
}
}, new Function<Map<String, Object>, String>() {
@Override
public String apply(Map<String, Object> stringObjectMap) {
return stringObjectMap.get("levelcode2").toString();
}
}));
这是一个将List<实体类>类型转换为map类型
class Book {
private String name;
private int releaseYear;
private String isbn;
}
public Map<String, String> listToMap(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getIsbn, Book::getName));
}
或者key值和value值都可以进行拼接
Map<String, BigDecimal> ksLabCostMap = cbhsXmftKsempcostEntityList.stream().collect(
Collectors.toMap(k -> k.getKscode()+"#"+k.getEmptitlecode(),part -> part.getUnittimecost())
);
2.2 冲突key处理
注意:当key值不唯一的时候,则需要引入一个合并函数,而这个合并函数使得保留了第一个key,后面如果有重复性的key值则不会被采纳
public Map<Integer, Book> listToMapWithDupKey(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
(existing, replacement) -> existing));
}
2.3 List 转 ConcurrentMap
1,什么是ConcurrentMap?
ConcurrentHashMap是一个线程安全,并且是一个高效的HashMap。
与HashMap不同的是,ConcurrentHashMap中多了一层数组结构,由Segment和HashEntry两个数组组成。其中Segment起到了加锁同步的作用,而HashEntry则起到了存储K.V键值对的作用。
在多线程中,每一个Segment对象守护了一个HashEntry数组,当对ConcurrentHashMap中的元素修改时,在获取到对应的Segment数组角标后,都会对此Segment对象加锁,之后再去操作后面的HashEntry元素,这样每一个Segment对象下,都形成了一个小小的HashMap,在保证数据安全性的同时,又提高了同步的效率。只要不是操作同一个Segment对象的话,就不会出现线程等待的问题!
相关链接:
Java集合–ConcurrentMap
ConcurrentHashMap 原理解析(JDK1.8
public Map<Integer, Book> listToConcurrentMap(List<Book> books) {
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(),
(o1, o2) -> o1, ConcurrentHashMap::new));
}
2.4 Sorted Map
public TreeMap<String, Book> listToSortedMap(List<Book> books) {
return books.stream()
.sorted(Comparator.comparing(Book::getName))
.collect(Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new));
}
参考链接:Java 8特性 - Collectors toMap
遇到到,补充一点(后面有空再补充):
根据实体类CbhsXmftUnitmapEntity中的ItemCode,Unitcode两个字段对实体进行去重处理,字段的先后顺序对最终的结果有影响
List<CbhsXmftUnitmapEntity> cbhsXmftUnitmapEntities =new LinkedList<>();
cbhsXmftUnitmapEntities = cbhsXmftUnitmapEntities.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(o -> o.getItemCode()+ "#" + o.getUnitcode()))),
ArrayList::new));