工具类篇2——集合工具类

`

集合工具类

工具类全都是阿里代码规范与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——线程池工具类》——待更新
《…》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值