
com.moon.core.util.GroupUtil Maven / Gradle / Ivy
package com.moon.core.util;
import com.moon.core.enums.Collects;
import com.moon.core.lang.ThrowUtil;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 分组工具,用于对数组、集合和{@link Iterator}进行分组
*
* @author moonsky
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public final class GroupUtil {
private GroupUtil() { ThrowUtil.noInstanceError(); }
/**
* 单元素分组,将集合或数组元素按元素进行分组,如果存在多个相同“键”,最终只会保留一个
*
* 如(伪代码):
*
* var list = [
* {id: 1, name: '上海'},
* {id: 2, name: '北京'},
* {id: 1, name: '广州'},
* ]
*
* var map = simplifyGroup(list, obj => obj.id);
* map like: {
* 1: {id: 1, name: '广州'},
* 2: {id: 2, name: '北京'},
* }
*
*
* 如需自定义 Map 类型,可参考如下:
*
* CollectUtil.reduce(collect, (resultMap, item, idx) -> {
* resultMap.put(grouper.apply(item), item);
* }, new LinkedHashMap());
*
*
* @param iterator 集合
* @param grouper 分组函数
* @param 键类型
* @param 元素类型
*
* @return 分组集合
*/
public static Map simplifyGroup(
Iterator extends E> iterator, Function super E, ? extends K> grouper
) {
HashMap resultMap = new HashMap(16);
if (iterator != null) {
while (iterator.hasNext()) {
E item = iterator.next();
resultMap.put(grouper.apply(item), item);
}
}
return resultMap;
}
/**
* 单元素分组,将集合或数组元素按元素进行分组,如果存在多个相同“键”,最终只会保留一个
*
* @param collect 集合
* @param grouper 分组函数
* @param 键类型
* @param 元素类型
*
* @return 分组集合
*/
public static Map simplifyGroup(
Iterable extends E> collect, Function super E, ? extends K> grouper
) {
if (collect instanceof Collection) {
return simplifyGroup((Collection) collect, grouper);
}
HashMap resultMap = new HashMap(16);
if (collect != null) {
for (E item : collect) {
resultMap.put(grouper.apply(item), item);
}
}
return resultMap;
}
/**
* 单元素分组,将集合或数组元素按元素进行分组,如果存在多个相同“键”,最终只会保留一个
*
* @param collect 集合
* @param grouper 分组函数
* @param 键类型
* @param 元素类型
*
* @return 分组集合
*/
public static Map simplifyGroup(
Collection extends E> collect, Function super E, ? extends K> grouper
) {
int len = collect == null ? 0 : collect.size();
HashMap resultMap = new HashMap(len);
if (collect != null) {
for (E item : collect) {
resultMap.put(grouper.apply(item), item);
}
}
return resultMap;
}
/**
* 单元素分组,将集合或数组元素按元素进行分组,如果存在多个相同“键”,最终只会保留一个
*
* @param arr 数组
* @param grouper 分组函数
* @param 键类型
* @param 元素类型
*
* @return 分组集合
*/
public static Map simplifyGroup(E[] arr, Function super E, ? extends K> grouper) {
int len = arr == null ? 0 : arr.length;
HashMap resultMap = new HashMap(len);
if (arr != null) {
for (E item : arr) {
resultMap.put(grouper.apply(item), item);
}
}
return resultMap;
}
/**
* 对数组分组,分组集合为{@code List}
*
* @param arr 待分组数组
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link List}集合,每个分组的值不可能为 null 或空集合。
*/
public static Map> groupAsList(E[] arr, Function super E, ? extends K> grouper) {
final Supplier supplier = Collects.ArrayLists;
return groupBy(arr, grouper, supplier);
}
/**
* 对数组分组,分组集合为{@code Set}
*
* @param arr 待分组数组
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link Set}集合,每个分组的值不可能为 null 或空集合,
* 但由于 Set 的性质,可能会有数据总数减少的情况。
*/
public static Map> groupAsSet(E[] arr, Function super E, ? extends K> grouper) {
final Supplier supplier = Collects.HashSets;
return groupBy(arr, grouper, supplier);
}
/**
* 对数组分组,分组集合由调用方自定义
*
* @param arr 待分组数组
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param groupingSupplier 每个分组集合由“创建器”提供
* @param 参照键数据类型
* @param 数组元素类型
* @param 分组集合类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,每个分组的值不可能为 null 或空集合。
*/
public static >
Map groupBy(E[] arr, Function super E, ? extends K> grouper, Supplier groupingSupplier) {
Map grouped = new HashMap<>();
final int len = arr == null ? 0 : arr.length;
for (int i = 0; i < len; i++) {
grouping(arr[i], grouped, grouper, groupingSupplier);
}
return grouped;
}
/**
* 对{@code List}集合分组
*
* @param list 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link List}集合,每个分组的值不可能为 null 或空集合。
*/
public static Map> groupAsList(
List list, Function super E, ? extends K> grouper
) {
final Supplier supplier = Collects.getOrDefault(list, Collects.ArrayLists);
return groupBy(list, grouper, supplier);
}
/**
* 对集合分组
*
* @param iterator 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link List}集合,每个分组的值不可能为 null 或空集合。
*/
public static Map> groupAsList(
Iterator iterator, Function super E, ? extends K> grouper
) {
final Supplier supplier = Collects.ArrayLists;
return groupBy(iterator, grouper, supplier);
}
/**
* 对{@code List}集合分组
*
* @param set 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link Set}集合,每个分组的值不可能为 null 或空集合,
* 但由于 Set 的性质,可能会有数据总数减少的情况。
*/
public static Map> groupAsSet(
Set set, Function super E, ? extends K> grouper
) {
final Supplier supplier = Collects.getOrDefault(set, Collects.HashSets);
return groupBy(set, grouper, supplier);
}
/**
* 对集合分组
*
* @param iterator 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link Set}集合,每个分组的值不可能为 null 或空集合,
* 但由于 Set 的性质,可能会有数据总数减少的情况。
*/
public static Map> groupAsSet(
Iterator iterator, Function super E, ? extends K> grouper
) {
final Supplier supplier = Collects.HashSets;
return groupBy(iterator, grouper, supplier);
}
/**
* 对集合分组
*
* @param collect 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param 参照键数据类型
* @param 数组元素类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,
* 值为数组项组成的{@link ArrayList}集合,每个分组的值不可能为 null 或空集合。
*/
public static Map> groupBy(
Collection collect, Function super E, ? extends K> grouper
) {
final Supplier supplier = Collects.getOrDefault(collect, Collects.ArrayLists);
return groupBy(collect, grouper, supplier);
}
/**
* 对集合分组
*
* @param collect 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param groupingSupplier 每个分组集合由“创建器”提供
* @param 参照键数据类型
* @param 数组元素类型
* @param 分组集合类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,每个分组的值不可能为 null 或空集合。
*/
public static > Map groupBy(
Iterable collect, Function super E, ? extends K> grouper, Supplier groupingSupplier
) {
Map grouped = new HashMap<>(8);
if (collect != null) {
for (E item : collect) {
grouping(item, grouped, grouper, groupingSupplier);
}
}
return grouped;
}
/**
* 对集合分组
*
* @param iterator 待分组集合
* @param grouper 分组函数,接受数组单项为参数,返回值为分组参照键
* 相同键名为同一组
* @param groupingSupplier 每个分组集合由“创建器”提供
* @param 参照键数据类型
* @param 数组元素类型
* @param 分组集合类型
*
* @return 分组后的元素以 Map 形式返回,Map 的键即为{@code grouper}的返回值,每个分组的值不可能为 null 或空集合。
*/
public static > Map groupBy(
Iterator iterator, Function super E, ? extends K> grouper, Supplier groupingSupplier
) {
Map grouped = new HashMap<>(8);
if (iterator != null) {
while (iterator.hasNext()) {
grouping(iterator.next(), grouped, grouper, groupingSupplier);
}
}
return grouped;
}
/**
* 单项分组执行器
*
* @param item 数据单项
* @param grouped 分组容器
* @param grouper 分组函数
* @param groupingSupplier 集合构造器
* @param 数据项类型
* @param 分组参照键类型
* @param 返回集合类型
*/
private static > void grouping(
E item, Map grouped, Function super E, ? extends K> grouper, Supplier groupingSupplier
) {
K key = grouper.apply(item);
CR group = grouped.get(key);
if (group == null) {
grouped.put(key, group = groupingSupplier.get());
}
group.add(item);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy