`
集合工具类
工具类全都是阿里代码规范与SonalLint扫描通过的哦,可以放心使用
2020年07月31日更新
经过两天的不断努力,我已经把工具包上传到公网啦!Maven引用地址如下
<dependency>
<groupId>com.gitee.taotaojs</groupId>
<artifactId>comn-basic</artifactId>
<version>1.0.0</version>
</dependency>
直接引用即可。
之后我也会出一个关于上传公网的踩坑手册,以及发布一下我用的CheckStyle文件检查相关异味,敬请期待!
【附上仓库地址】
阿里云的Maven仓库
sonatype仓库
2020年08月10日更新
增加根据配置可以将一组数据固定分组,且确定每组元素个数。还支持有map的key直接分组【fixedGrouping()】
注意事项:
本工具类有使用到同包下的工具类,详情请看gitee的代码,有所有工具类的代码~
import com.taotaojs.exception.MyInnerException; - 内部异常类,直接继承RuntimeException
import com.taotaojs.util.number.NumberFormatUtil; - 数字格式化工具类
import com.taotaojs.util.reflect.ReflectUtil; - 反射工具类
(后期全都会在CSDN上更新的)
主要功能
- 将集合转换为以指定分隔符分隔的字符串【toString()】
- 将已被固定字符分隔成的字符串拆分为指定类型集合【get***()】
- 获取集合中复杂对象某个属性并整理为集合【get***()】
- 比较两个复杂或基本类型集合对结果返回交集【compareToArray***()】
- 获取集合中重复的对象集合并去重【getRepeat()】
- 判断Map与Collection对应对象是否为空【isEmpty(), isNotEmpty()】
- 判断Map与Collection为空就新建的逻辑【isCreate***()】
- 判断集合/数组中是否存在某个元素
功能详解
有些功能比较难以理解,我就说说我在实际项目中的应用
比较两个复杂类型集合对结果返回交集
这个方法可以直接将两个集合对象交集取出,并且将原集合的元素删除(如果两个集合的判断属性全都为空就默认采用equals方法),一般我用这个来去除新增或修改时的重复值。
就比如一个DB对象集合与一个VO对象集合执行了此方法,就会出现三个集合:
- 剩余的DB对象集合,这个集合里面全都是前端没有传过来的,如果逻辑上有需要,可以直接将整个集合对象从数据中删除
- 剩余的VO对象集合,这个集合里都是数据库中还未存在的,可如果逻辑上有需要,可以直接将整个集合对象插入数据库中
- 两个集合的交集,这个集合比较特殊,因为他有VO的身体,DB的主键,可以直接根据主键来更新数据库中的数据
而除了这个三个集合之外,这三个集合还可以相互组合形成如下图所示的功能
这个方法在开发去重数据库增删改的逻辑时,使用频率特别高,所以底层我也进行了逻辑上的优化,复杂度(2O),使用的是迭代器模式,可以放心使用
注意:需要重写实体对象的equals和hashCode方法哦
具体代码
package com.gitee.taotaojs.util;
import com.gitee.taotaojs.exception.MyInnerException;
import com.gitee.taotaojs.util.number.NumberFormatUtil;
import com.gitee.taotaojs.util.reflect.ReflectUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
/**
* 集合工具类
*
* @author TaoTaojs
* @author TaoTaojs
* @date 2020/7/2 2:23 PM
* <p>Description</p>
* 将集合转换为以指定分隔符分隔的字符串【toString()】
* 将已被固定字符分隔成的字符串拆分为指定类型集合【get***()】
* 获取集合中复杂对象某个属性并整理为集合【get***()】
* 比较两个复杂或基本类型集合对结果返回交集【compareToArray***()】
* 获取集合中重复的对象集合并去重【getRepeat()】
* 判断Map与Collection对应对象是否为空【isEmpty(), isNotEmpty()】
* 判断Map与Collection为空就新建的逻辑【isCreate***()】
* 判断集合/数组中是否存在某个元素
* 将一组数据固定分组,每组n个元素
* 关联类:
* 参考链接:
* History: <br/>
* <author> <time> <version> <desc>
* TaoTaojs 2020/7/2 2:23 PM V1.0 支持将集合转换为以分隔符分隔的字符串,获取集合中对象某个不确定类型属性并整理为集合,比较两个复杂或基本类型集合对结果返回交集,获取集合中重复的对象集合并去重
* TaoTaojs 2020年08月10日10:38:16 V1.0 将一组数据固定分组,每组n个元素
*/
public final class CollectionUtil {
private CollectionUtil() { }
/**
* 将集合转换为逗号分隔的字符串
* @param list toString()有效的对象集合
* @param <T> 指定泛型
* @return 返回逗号分隔的字符串
*/
public static<T> String toString(List<T> list) {
if (CollectionUtil.isEmpty(list)) {
return "";
}
return StringUtil.join(list.toArray());
}
/**
* 获取自定义属性并整理成集合
* @param list 需要被提取属性的对象集合
* @param calzz 被提取属性对象的类型
* @param methodName 提取方法的名称
* @param <T> 属性的泛型
* @param <V> 被提取属性对象泛型
* @return 返回集合列表
*/
public static<T, V> List<T> getPros(List<V> list, Class<V> calzz, String methodName) {
List<T> reList = new ArrayList<>();
Method getMethod = ReflectUtil.getGetMethod(calzz, methodName);
for (V v : list) {
try {
Object pro = getMethod.invoke(v);
if (pro != null) {
reList.add((T) pro);
}
} catch (Exception e) {
throw new MyInnerException(e);
}
}
return reList;
}
/**
* 将字符串转换成Integer集合
* @param listStr 以指定字符分隔的字符串
* @param regex 指定字符
* @return 由字符串转换成的Integer集合
*/
public static List<Integer> getInteger(String listStr, String regex) {
if (StringUtil.isBlank(listStr) || StringUtil.isBlank(regex)) {
return new ArrayList<>();
}
return Arrays.asList(listStr.split(regex)).stream()
.filter(str -> !str.isEmpty())
.map(NumberFormatUtil::stringToInteger)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
/**
* 将字符串转换为string集合
* @param listStr 以指定字符分隔的字符串
* @param regex 指定字符
* @return 由字符串转换成的String集合
*/
public static List<String> getStrs(String listStr, String regex) {
if (StringUtil.isBlank(listStr) || StringUtil.isBlank(regex)) {
return new ArrayList<>();
}
return Arrays.asList(listStr.split(regex)).stream()
.filter(str -> !str.isEmpty())
.collect(Collectors.toList());
}
/**
* 将字符串转换为数字集合(双精度集合)
* @param listStr 以指定字符分隔的字符串
* @param regex 指定字符
* @return 由字符串转成成的Double集合
*/
public static List<Double> getNumber(String listStr, String regex) {
if (StringUtil.isBlank(listStr) || StringUtil.isBlank(regex)) {
return new ArrayList<>();
}
return Arrays.asList(listStr.split(regex)).stream()
.filter(str -> !str.isEmpty())
.map(NumberFormatUtil::stringToDouble)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<T> List<Integer> getIds(List<T> list, Class<T> clazz){
return getPros(list, clazz, "id");
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static List<Integer> getIds(String listStr){
return getInteger(listStr, ",");
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static List<Integer> getInteger(String listStr){
return getInteger(listStr, ",");
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<T> List<String> getStrs(List<T> list, Class<T> clazz, String methodName){
return getPros(list, clazz, methodName);
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static List<String> getStrs(String listStr){
return getStrs(listStr);
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<T> List<Integer> getNumber(List<T> list, Class<T> clazz, String methodName){
return getPros(list, clazz, methodName);
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static List<Double> getNumber(String listStr){
return getNumber(listStr);
}
/**
* 排除集合中的空值
* @param coll 集合
* @param <T> 集合泛型
*/
public static <T> void toNotEmpty(Collection<T> coll) {
Iterator<T> it = coll.iterator();
while (it.hasNext()) {
T x = it.next();
if (x == null) {
it.remove();
}
}
}
/**
* 比较两个集合,找出其中的交集,并返回(找到过程中会删除原来两个集合中的数据引用) - 使用equals判断
* @param clazz 对象类型
* @param listDb DB - 返回一个需要删除的列表
* @param listVO VO - 返回一个需要添加的列表
* @param keyName 主键属性字段/关键属性字段
* @param <T> 对象类型
* @return 返回两个集合的交集 - 返回一个需要修改的列表
*/
public static<T> List<T> compareToArray(Class<T> clazz, List<T> listDb, List<T> listVO, String keyName){
List<T> list = new ArrayList<>();
if(listDb == null || listVO == null) {
return list;
}
toNotEmpty(listDb);
toNotEmpty(listVO);
Method getKeyMethod = ReflectUtil.getGetMethod(clazz, keyName);
Method setKeyMethod = ReflectUtil.getSetMethod(clazz, keyName, getKeyMethod.getReturnType());
Iterator<T> iterator1 = listDb.iterator();
while(iterator1.hasNext()){
T item1 = iterator1.next();
Iterator<T> iterator2 = listVO.iterator();
while(iterator2.hasNext()){
T item2 = iterator2.next();
if(compareToArrayReturnJudge(getKeyMethod, setKeyMethod, item1, item2)){
iterator1.remove();
iterator2.remove();
list.add(item2);
break;
}
}
}
return list;
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<T> List<T> compareToArray(Class<T> clazz, List<T> listDb, List<T> listVO){
return compareToArray(clazz, listDb, listVO, "id");
}
/**
* 比较两个集合并获取交集方法的主要处理方法(为了降低代码复杂度,特拆开)
* @param getKeyMethod 获取key的方法对象
* @param setKeyMethod 设置key的方法对象
* @param item1 对象1
* @param item2 对象2
* @param <T> 对象类类型
* @return 是否相同
*/
private static<T> boolean compareToArrayReturnJudge(Method getKeyMethod, Method setKeyMethod, T item1, T item2){
Object key1 = ReflectUtil.invokeMethod(item1, getKeyMethod);
Object key2 = ReflectUtil.invokeMethod(item2, getKeyMethod);
if (key1 != null && key2 != null && key1.equals(key2)) {
//如果两个对象都有key值,且key值相同
return true;
} else if (key1 != null && key2 == null && item1.equals(item2)){
//如果VO没有key值,且两个对象equals相同
ReflectUtil.invokeMethod(item2, setKeyMethod, key1);
return true;
} else if (key1 == null && key2 != null && item1.equals(item2)){
//如果DB没有key值,且两个对象equals相同
return true;
}
return false;
}
/**
* 对比基本类型集合的方法(直接对比equals方法)
* @param list1 基本类型集合1
* @param list2 基本类型集合2
* @param <T> 基本类型泛型
* @return 交集集合
*/
public static<T> List<T> compareToArrayBasic(List<T> list1, List<T> list2){
List<T> list = new ArrayList<>();
if(list1 == null || list2 == null) {
return list;
}
Iterator<T> iterator1 = list1.iterator();
while(iterator1.hasNext()) {
T item1 = iterator1.next();
Iterator<T> iterator2 = list2.iterator();
while (iterator2.hasNext()) {
T item2 = iterator2.next();
if(item1.equals(item2)){
iterator1.remove();
iterator2.remove();
list.add(item2);
break;
}
}
}
return list;
}
/**
* 获取一个集合中重复的对象并返回为一个集合
* @param data 集合
* @param <T> 集合泛型
* @return 集合中的重复对象
*/
public static<T> List<T> getRepeat(List<T> data){
List<T> list = new ArrayList<>();
Iterator<T> iterator1 = data.iterator();
while(iterator1.hasNext()) {
T item1 = iterator1.next();
Iterator<T> iterator2 = data.iterator();
while (iterator2.hasNext()) {
T item2 = iterator2.next();
if(item1.equals(item2)){
iterator2.remove();
list.add(item2);
break;
}
}
}
return list;
}
/**
* 判断Collection对象与Map对象是否为空
* @param collection 集合
* @return 如果为空则返回对应的数据
*/
@SuppressWarnings("checkstyle:JavadocMethod")
public static boolean isEmpty(Collection<?> collection) {
return (collection == null || collection.isEmpty());
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static boolean isNotEmpty(Collection<?> collection) {
return (collection != null && !collection.isEmpty());
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<K, V> boolean isEmpty(Map<K, V> map){
return map == null || map.size() == 0;
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static<K, V> boolean isNotEmpty(Map<K, V> map){
return map != null && map.size() > 0;
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static boolean isEmpty(Object[] collection) {
return (collection == null || collection.length == 0);
}
@SuppressWarnings("checkstyle:JavadocMethod")
public static boolean isNotEmpty(Object[] collection) {
return (collection != null && collection.length > 0);
}
/**
* 如果Map的key对应的value为空,则根据类型
* @param map map集合
* @param key 指定主键值
* @param clazz value类型
*/
public static void isCreateMap(Map map, Object key, Class<?> clazz){
Object obj = map.get(key);
if(obj == null){
if(clazz.equals(List.class)){
map.put(key, new ArrayList<>());
}else if(clazz.equals(Set.class)){
map.put(key, new HashSet<>());
}else if(clazz.equals(Map.class)){
map.put(key, new HashMap<>(ConstantUtil.TWO));
}else if(clazz.equals(ArrayList.class)){
map.put(key, new ArrayList<>());
}else if(clazz.equals(LinkedHashSet.class)){
map.put(key, new LinkedHashSet<>());
}else if(clazz.equals(TreeSet.class)){
map.put(key, new TreeSet<>());
}else if(clazz.equals(TreeMap.class)){
map.put(key, new TreeMap<>());
}else if(clazz.equals(LinkedHashMap.class)){
map.put(key, new LinkedHashMap<>());
}
}
}
/**
* 如果集合为空,则返回对应实例
* @param collection 集合
* @param <T> 集合泛型
* @return 如果集合为空,则返回对应实例
*/
public static<T> List<T> isCreateList(List<T> collection){
if(collection == null) {
collection = new ArrayList<>();
}
return collection;
}
/**
* 如果集合为空,则返回对应实例
* @param collection 集合
* @param <T> 集合泛型
* @return 如果集合为空,则返回对应实例
*/
public static<T> Set<T> isCreateSet(Set<T> collection){
if(collection == null) {
collection = new HashSet<>();
}
return collection;
}
/**
* 判断集合/数组中是否存在某个元素
* @param objs 数组
* @param obj 对应的元素,需要查找的元素
* @param clazz 元素类型
* @param pros 用于判断的属性
* @param <T> 元素泛型
* @return 如果pros没传,则直接查询,如果有pros,则使用对应属性比较
*/
public static<T> boolean isExist(T[] objs, T obj, Class<T> clazz, String... pros){
if(objs == null){
return false;
}
List<T> objList = new ArrayList<>();
objList.addAll(Arrays.asList(objs));
if(isEmpty(pros)){
return objList.contains(obj);
}else{
for (String proStr : pros) {
T pro = ReflectUtil.invokeMethod(obj, proStr);
List<T> proList = getPros(objList, clazz, proStr);
if(proList.contains(pro)){
return true;
}
}
}
return false;
}
/**
* 将一组数据固定分组,每组n个元素
* @param source 要分组的数据源
* @param n 每组n个元素
* @param <T>
* @return
*/
public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {
if (null == source || source.size() == 0 || n <= 0)
return null;
List<List<T>> result = new ArrayList<List<T>>();
int remainder = source.size() % n;
int size = (source.size() / n);
for (int i = 0; i < size; i++) {
List<T> subset = null;
subset = source.subList(i * n, (i + 1) * n);
result.add(subset);
}
if (remainder > 0) {
List<T> subset = null;
subset = source.subList(size * n, size * n + remainder);
result.add(subset);
}
return result;
}
/**
* 将一组数据固定分组,每组n个元素
* @param basicMap Map类型的数据,key必须为Integer类型
* @param n 每组几个
* @param sum 总长度,如果超出总长度将会抛弃
* @return
*/
public static List<List> fixedGrouping(Map<Integer, ?> basicMap, int n, int sum) {
Map<Integer, ?> sourceMap = new HashMap<>(basicMap);
List<Integer> source = new ArrayList<>(sourceMap.keySet());
if (null == source || source.size() == 0 || n <= 0)
return null;
List<List> result = new ArrayList<>();
List subset = new ArrayList<>();
for (int i = 1; i <= sum; i++) {
Object temp = sourceMap.get(i);
if(temp != null){
subset.add(temp);
sourceMap.remove(i);
}
if((i) % n == 0) {
result.add(new ArrayList(subset));
subset.clear();
}
}
return result;
}
}
文章链接
《工具类篇1——POI工具类》——待更新
《工具类篇2——集合工具类》
《工具类篇3——反射工具类》(共三篇)
《工具类篇4——大数字工具类》(共三篇)——待更新
《工具类篇5——时间戳工具类》(共两篇)——待更新
《工具类篇6——字符串工具类》——待更新
《工具类篇7——线程池工具类》——待更新
《…》