本文源码可运行的 JDK 版本要求:JDK 1.8 +
本文源码参见:github.com/woodwhales/…
一般在业务开发中,开发者会先通过 ORM 框架查询数据库数据得到数据的 List 集合,再该业务数据集合做如下处理:
List 集合转 Map 集合
按照 List 集合元素中某个属性将 List 集合转 Map 集合
在 JDK 1.8 版本中可以使用 stream 快速将 list 转 map:
// 第一种 直接返回user本身
Map<Long, User> map = userList.stream().collect(Collectors.toMap(User::getId, user -> user));
// 第二种 Function中有一个static方法identity 返回本身
Map<Long, User> map = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
// 如果list中的age存在相同的时候,转化map的时候就会出错Duplicate key
// toMap的重载,定义key2覆盖key1的值
Map<Integer, Users> map3 = list.stream().collect(Collectors.toMap(Users::getId, Function.identity(), (key1,key2) -> key2));
笔者利用上述代码进行二次封装,简化了判空及转 map 时填写 .stream().collect… 等重复的代码。
public class DataTool {
/**
* list 转 map 集合
* @param source 数据源集合
* @param keyMapper map 集合中的 key 获取规则
* @param valueMapper map 集合中的 value 获取规则
* @param <K> map 集合中的 key 类型
* @param <S> 数据源集合中元素的类型
* @param <T> map 集合中的 value 类型
* @return
*/
public static <K, S, T> Map<K,T> toMap(List<S> source,
Function<? super S, ? extends K> keyMapper,
Function<? super S, ? extends T> valueMapper) {
if(null == source || source.size() == 0) {
return Collections.emptyMap();
}
return source.stream().collect(Collectors.toMap(keyMapper, valueMapper));
}
}
源码参见:src/main/java/org/woodwhales/business/DataTool.java
List 集合分组
List 集合按照某种规则进行分组
在 JDK 1.8 版本中可以使用 stream 快速将 list 分组:
Map<String, List<User>> group = list.stream().collect(Collectors.groupingBy(User::getType));
笔者利用上述代码进行二次封装,简化了判空及转 map 时填写 .stream().collect… 等重复的代码。
public class DataTool {
/**
* 将 list 集合分组
* @param source 数据源集合
* @param classifier 分组规则
* @param <K> map 集合中的 key 类型
* @param <S> map 集合中的 value 类型
* @return
*/
public static <K, S> Map<K, List<S>> groupingBy(List<S> source,
Function<? super S, ? extends K> classifier) {
if(null == source || source.size() == 0) {
return Collections.emptyMap();
}
return source.stream().collect(Collectors.groupingBy(classifier));
}
}
源码参见:src/main/java/org/woodwhales/business/DataTool.java
业务数据去重
List 集合按照指定属性去重(其中可能存在要去重的属性不存在,即“无效的”数据)。
利用 Map 集合存入元素方法 put() 的特性:已存在则返回旧的元素,不存在则返回空。
public class DataTool {
/**
* 对集合数据进行去重器
* 非线程安全
* @param source 数据源集合
* @param deduplicateInterface 去重器接口
* @param <K> 去重属性的类型
* @param <T> 数据源集合中元素的类型
* @return
*/
public static <K, T> DeduplicateResult<T> deduplicate(List<T> source,
DeduplicateInterface<K, T> deduplicateInterface) {
if(null == source || source.size() == 0) {
return new DeduplicateResult<T>(source, emptyList(), emptyList(), emptyList());
}
Map<K, T> container = new LinkedHashMap<>();
// 无效的数据集合
List<T> invalidList = new LinkedList<>();
// 重复的数据集合
List<T> repetitiveList = new LinkedList<>();
for (T data : source) {
if (!deduplicateInterface.isValid(data)) {
invalidList.add(data);
} else {
K deduplicatedKey = deduplicateInterface.getDeduplicatedKey(data);
T putData = container.put(deduplicatedKey, data);
if(Objects.nonNull(putData)) {
repetitiveList.add(putData);
}
}
}
// 已去重的数据集合
List<T> deduplicatedList = new ArrayList<>(container.values());
return new DeduplicateResult<T>(source, invalidList, deduplicatedList, repetitiveList);
}
}
源码参见:src/main/java/org/woodwhales/business/DataTool.java
枚举转 map 集合
根据枚举中某个属性进行枚举转 map 集合。
利用 EnumSet 类的 allOf() 方法,可以根据枚举的 Class 类型获取该枚举的所有枚举实例。当拿到集合枚举数据就可以使用 stream 进行集合转 map。
public class DataTool {
/**
* 枚举转 map 集合
* @param sourceEnumClass 数据源枚举 Class类
* @param keyMapper map 集合中的 key 获取规则
* @param <K> map 集合中的 key 类型
* @param <T> map 集合中的 value 类型
* @return
*/
public static <K, T extends Enum<T>> Map<K, T> enumMap(Class<T> sourceEnumClass,
Function<? super T, ? extends K> keyMapper) {
EnumSet<T> enumSet = EnumSet.allOf(sourceEnumClass);
return enumSet.stream().collect(Collectors.toMap(keyMapper, Function.identity()));
}
}
源码参见:src/main/java/org/woodwhales/business/DataTool.java
个人博客:woodwhale's blog
博客园:木鲸鱼的博客