All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.base4j.util.CollectionUtil Maven / Gradle / Ivy

The newest version!
package com.base4j.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;

import com.base4j.util.lang.BoundedPriorityQueue;
import com.base4j.util.lang.Filter;

import com.google.common.collect.Maps;

/**
 * 集合相关工具类,包括数组
 *
 * @author xxx
 */
public class CollectionUtil {
    public static final String SPLIT_STR = ",";

    private CollectionUtil() {
        // 静态类不可实例化
    }

    /**
     * 以 conjunction 为分隔符将集合转换为字符串
     *
     * @param          被处理的集合
     * @param collection  集合
     * @param conjunction 分隔符
     * @return 连接后的字符串
     */
    public static  String join(Iterable collection, String conjunction) {
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (T item : collection) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append(conjunction);
            }
            sb.append(item);
        }
        return sb.toString();
    }

    /**
     * 以 conjunction 为分隔符将数组转换为字符串
     *
     * @param          被处理的集合
     * @param array       数组
     * @param conjunction 分隔符
     * @return 连接后的字符串
     */
    public static  String join(T[] array, String conjunction) {
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (T item : array) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append(conjunction);
            }
            sb.append(item);
        }
        return sb.toString();
    }

    /**
     * 将多个集合排序并显示不同的段落(分页)
     *
     * @param pageNo     页码
     * @param numPerPage 每页的条目数
     * @param comparator 比较器
     * @param colls      集合数组
     * @return 分页后的段落内容
     */
    @SafeVarargs
    public static  List sortPageAll(int pageNo, int numPerPage, Comparator comparator, Collection... colls) {
        final List result = new ArrayList<>();
        for (Collection coll : colls) {
            result.addAll(coll);
        }

        Collections.sort(result, comparator);

        // 第一页且数目少于第一页显示的数目
        if (pageNo <= 1 && result.size() <= numPerPage) {
            return result;
        }

        final int[] startEnd = PageUtil.transToStartEnd(pageNo, numPerPage);
        return result.subList(startEnd[0], startEnd[1]);
    }

    /**
     * 将多个集合排序并显示不同的段落(分页)
     *
     * @param pageNo     页码
     * @param numPerPage 每页的条目数
     * @param comparator 比较器
     * @param colls      集合数组
     * @return 分业后的段落内容
     */
    @SafeVarargs
    public static  List sortPageAll2(int pageNo, int numPerPage, Comparator comparator, Collection... colls) {
        BoundedPriorityQueue queue = new BoundedPriorityQueue<>(pageNo * numPerPage);
        for (Collection coll : colls) {
            queue.addAll(coll);
        }

        // 第一页且数目少于第一页显示的数目
        if (pageNo <= 1 && queue.size() <= numPerPage) {
            return queue.toList();
        }

        final int[] startEnd = PageUtil.transToStartEnd(pageNo, numPerPage);
        return queue.toList().subList(startEnd[0], startEnd[1]);
    }

    /**
     * 将Set排序(根据Entry的值)
     *
     * @param set 被排序的Set
     * @return 排序后的Set
     */
    public static List> sortEntrySetToList(Set> set) {
        List> list = new LinkedList>(set);
        Collections.sort(list, new Comparator>() {

            @Override
            public int compare(Entry o1, Entry o2) {
                if (o1.getValue() > o2.getValue()) {
                    return 1;
                }
                if (o1.getValue() < o2.getValue()) {
                    return -1;
                }
                return 0;
            }
        });
        return list;
    }

    /**
     * 切取部分数据
     *
     * @param              集合元素类型
     * @param surplusAlaDatas 原数据
     * @param partSize        每部分数据的长度
     * @return 切取出的数据或null
     */
    public static  List popPart(Stack surplusAlaDatas, int partSize) {
        if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0) {
            return null;
        }

        final List currentAlaDatas = new ArrayList<>();
        int size = surplusAlaDatas.size();
        // 切割
        if (size > partSize) {
            for (int i = 0; i < partSize; i++) {
                currentAlaDatas.add(surplusAlaDatas.pop());
            }
        } else {
            for (int i = 0; i < size; i++) {
                currentAlaDatas.add(surplusAlaDatas.pop());
            }
        }
        return currentAlaDatas;
    }

    /**
     * 切取部分数据
     *
     * @param              集合元素类型
     * @param surplusAlaDatas 原数据
     * @param partSize        每部分数据的长度
     * @return 切取出的数据或null
     */
    public static  List popPart(Deque surplusAlaDatas, int partSize) {
        if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0) {
            return null;
        }

        final List currentAlaDatas = new ArrayList();
        int size = surplusAlaDatas.size();
        // 切割
        if (size > partSize) {
            for (int i = 0; i < partSize; i++) {
                currentAlaDatas.add(surplusAlaDatas.pop());
            }
        } else {
            for (int i = 0; i < size; i++) {
                currentAlaDatas.add(surplusAlaDatas.pop());
            }
        }
        return currentAlaDatas;
    }

    /**
     * 新建一个HashMap
     *
     * @return HashMap对象
     */
    public static  HashMap newHashMap() {
        return new HashMap();
    }

    /**
     * 新建一个HashMap
     *
     * @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75
     * @return HashMap对象
     */
    public static  HashMap newHashMap(int size) {
        return new HashMap((int) (size / 0.75));
    }

    /**
     * 新建一个HashSet
     *
     * @param ts 元素数组
     * @return HashSet对象
     */
    @SafeVarargs
    public static  HashSet newHashSet(T... ts) {
        HashSet set = new HashSet();
        for (T t : ts) {
            set.add(t);
        }
        return set;
    }

    /**
     * 新建一个HashSet
     *
     * @return HashSet对象
     */
    public static  HashSet newHashSet(Collection collection) {
        HashSet set = new HashSet();
        set.addAll(collection);
        return set;
    }

    /**
     * 新建一个ArrayList
     *
     * @param values 数组
     * @return ArrayList对象
     */
    @SafeVarargs
    public static  ArrayList newArrayList(T... values) {
        ArrayList arrayList = new ArrayList<>();
        for (T t : values) {
            arrayList.add(t);
        }
        return arrayList;
    }

    /**
     * 新建一个ArrayList
     *
     * @param collection 集合
     * @return ArrayList对象
     */
    public static  ArrayList newArrayList(Collection collection) {
        return new ArrayList<>(collection);
    }

    /**
     * 将新元素添加到已有数组中
* 添加新元素会生成一个新的数组,不影响原数组 * * @param buffer 已有数组 * @param newElement 新元素 * @return 新数组 */ public static T[] append(T[] buffer, T newElement) { T[] t = resize(buffer, buffer.length + 1, newElement.getClass()); t[buffer.length] = newElement; return t; } /** * 生成一个新的重新设置大小的数组 * * @param buffer 原数组 * @param newSize 新的数组大小 * @param componentType 数组元素类型 * @return 调整后的新数组 */ public static T[] resize(T[] buffer, int newSize, Class componentType) { T[] newArray = newArray(componentType, newSize); System.arraycopy(buffer, 0, newArray, 0, buffer.length >= newSize ? newSize : buffer.length); return newArray; } /** * 新建一个空数组 * * @param componentType 元素类型 * @param newSize 大小 * @return 空数组 */ @SuppressWarnings("unchecked") public static T[] newArray(Class componentType, int newSize) { return (T[]) Array.newInstance(componentType, newSize); } /** * 生成一个新的重新设置大小的数组
* 新数组的类型为原数组的类型 * * @param buffer 原数组 * @param newSize 新的数组大小 * @return 调整后的新数组 */ public static T[] resize(T[] buffer, int newSize) { return resize(buffer, newSize, buffer.getClass().getComponentType()); } /** * 将多个数组合并在一起
* 忽略null的数组 * * @param arrays 数组集合 * @return 合并后的数组 */ @SafeVarargs public static T[] addAll(T[]... arrays) { if (arrays.length == 1) { return arrays[0]; } int length = 0; for (T[] array : arrays) { if (array == null) { continue; } length += array.length; } T[] result = newArray(arrays.getClass().getComponentType().getComponentType(), length); length = 0; for (T[] array : arrays) { if (array == null) { continue; } System.arraycopy(array, 0, result, length, array.length); length += array.length; } return result; } /** * 克隆数组 * * @param array 被克隆的数组 * @return 新数组 */ public static T[] clone(T[] array) { if (array == null) { return null; } return array.clone(); } /** * 生成一个数字列表
* 自动判定正序反序 * * @param excludedEnd 结束的数字(不包含) * @return 数字列表 */ public static int[] range(int excludedEnd) { return range(0, excludedEnd, 1); } /** * 生成一个数字列表
* 自动判定正序反序 * * @param includedStart 开始的数字(包含) * @param excludedEnd 结束的数字(不包含) * @return 数字列表 */ public static int[] range(int includedStart, int excludedEnd) { return range(includedStart, excludedEnd, 1); } /** * 生成一个数字列表
* 自动判定正序反序 * * @param includedStart 开始的数字(包含) * @param excludedEnd 结束的数字(不包含) * @param step 步进 * @return 数字列表 */ public static int[] range(int includedStart, int excludedEnd, int step) { if (includedStart > excludedEnd) { int tmp = includedStart; includedStart = excludedEnd; excludedEnd = tmp; } if (step <= 0) { step = 1; } int deviation = excludedEnd - includedStart; int length = deviation / step; if (deviation % step != 0) { length += 1; } int[] range = new int[length]; for (int i = 0; i < length; i++) { range[i] = includedStart; includedStart += step; } return range; } /** * 截取数组的部分 * * @param list 被截取的数组 * @param start 开始位置(包含) * @param end 结束位置(不包含) * @return 截取后的数组,当开始位置超过最大时,返回null */ public static List sub(List list, int start, int end) { if (list == null || list.isEmpty()) { return null; } if (start < 0) { start = 0; } if (end < 0) { end = 0; } if (start > end) { int tmp = start; start = end; end = tmp; } final int size = list.size(); if (end > size) { if (start >= size) { return null; } end = size; } return list.subList(start, end); } /** * 截取集合的部分 * * @param list 被截取的数组 * @param start 开始位置(包含) * @param end 结束位置(不包含) * @return 截取后的数组,当开始位置超过最大时,返回null */ public static List sub(Collection list, int start, int end) { if (list == null || list.isEmpty()) { return null; } return sub(new ArrayList(list), start, end); } /** * 过滤 * * @param array 数组 * @param filter 过滤器接口 * @return 过滤后的数组 */ public static T[] filter(T[] array, Filter filter) { ArrayList list = new ArrayList(); T modified; for (T t : array) { modified = filter.modify(t); if (null != modified) { list.add(t); } } return list.toArray(Arrays.copyOf(array, list.size())); } /** * 过滤
* 过滤会改变原集合的内容 * * @param collection 集合 * @param filter 过滤器接口 * @return 过滤后的数组 */ public static Collection filter(Collection collection, Filter filter) { Collection collection2 = ObjectUtil.clone(collection); collection2.clear(); T modified; for (T t : collection) { modified = filter.modify(t); if (null != modified) { collection2.add(t); } } return collection2; } /** * 过滤 * * @param map Map * @param filter 过滤器 * @return 过滤后的Map */ public static Map filter(Map map, Filter> filter) { Map map2 = ObjectUtil.clone(map); map2.clear(); Entry modified; for (Entry entry : map.entrySet()) { modified = filter.modify(entry); if (null != modified) { map2.put(entry.getKey(), entry.getValue()); } } return map2; } /** * 数组是否为空 * * @param array 数组 * @return 是否为空 */ public static boolean isEmpty(T[] array) { return array == null || array.length <= 0; } /** * 数组是否为非空 * * @param array 数组 * @return 是否为非空 */ public static boolean isNotEmpty(T[] array) { return false == isEmpty(array); } /** * 集合是否为空 * * @param collection 集合 * @return 是否为空 */ public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } /** * 集合是否为非空 * * @param collection 集合 * @return 是否为非空 */ public static boolean isNotEmpty(Collection collection) { return false == isEmpty(collection); } /** * Map是否为空 * * @param map 集合 * @return 是否为空 */ public static boolean isEmpty(Map map) { return map == null || map.isEmpty(); } /** * Map是否为非空 * * @param map 集合 * @return 是否为非空 */ public static boolean isNotEmpty(Map map) { return false == isEmpty(map); } /** * 映射键值(参考Python的zip()函数)
* 例如:
* keys = [a,b,c,d]
* values = [1,2,3,4]
* 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param keys 键列表 * @param values 值列表 * @return Map */ public static Map zip(T[] keys, K[] values) { if (isEmpty(keys) || isEmpty(values)) { return null; } final int size = Math.min(keys.length, values.length); final Map map = new HashMap((int) (size / 0.75)); for (int i = 0; i < size; i++) { map.put(keys[i], values[i]); } return map; } /** * 映射键值(参考Python的zip()函数)
* 例如:
* keys = a,b,c,d
* values = 1,2,3,4
* delimiter = , 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param keys 键列表 * @param values 值列表 * @return Map */ public static Map zip(String keys, String values, String delimiter) { return zip(StrUtil.split(keys, delimiter), StrUtil.split(values, delimiter)); } /** * 映射键值(参考Python的zip()函数)
* 例如:
* keys = [a,b,c,d]
* values = [1,2,3,4]
* 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param keys 键列表 * @param values 值列表 * @return Map */ public static Map zip(Collection keys, Collection values) { if (isEmpty(keys) || isEmpty(values)) { return null; } final List keyList = new ArrayList(keys); final List valueList = new ArrayList(values); final int size = Math.min(keys.size(), values.size()); final Map map = new HashMap((int) (size / 0.75)); for (int i = 0; i < size; i++) { map.put(keyList.get(i), valueList.get(i)); } return map; } /** * 数组中是否包含元素 * * @param array 数组 * @param value 被检查的元素 * @return 是否包含 */ public static boolean contains(T[] array, T value) { final Class componetType = array.getClass().getComponentType(); boolean isPrimitive = false; if (null != componetType) { isPrimitive = componetType.isPrimitive(); } for (T t : array) { if (t == value) { return true; } else if (false == isPrimitive && null != value && value.equals(t)) { return true; } } return false; } /** * 将Entry集合转换为HashMap * * @param entryCollection entry集合 * @return Map */ public static HashMap toMap(Collection> entryCollection) { HashMap map = new HashMap(); for (Entry entry : entryCollection) { map.put(entry.getKey(), entry.getValue()); } return map; } /** * 将集合转换为排序后的TreeSet * * @param collection 集合 * @param comparator 比较器 * @return treeSet */ public static TreeSet toTreeSet(Collection collection, Comparator comparator) { final TreeSet treeSet = new TreeSet(comparator); for (T t : collection) { treeSet.add(t); } return treeSet; } /** * 排序集合 * * @param collection 集合 * @param comparator 比较器 * @return treeSet */ public static List sort(Collection collection, Comparator comparator) { List list = new ArrayList(collection); Collections.sort(list, comparator); return list; } // ------------------------------------------------------------------- 基本类型的数组转换为包装类型数组 /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Integer[] wrap(int... values) { final int length = values.length; Integer[] array = new Integer[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Long[] wrap(long... values) { final int length = values.length; Long[] array = new Long[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Character[] wrap(char... values) { final int length = values.length; Character[] array = new Character[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Byte[] wrap(byte... values) { final int length = values.length; Byte[] array = new Byte[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Short[] wrap(short... values) { final int length = values.length; Short[] array = new Short[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Float[] wrap(float... values) { final int length = values.length; Float[] array = new Float[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Double[] wrap(double... values) { final int length = values.length; Double[] array = new Double[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 将基本类型数组包装为包装类型 * * @param values 基本类型数组 * @return 包装类型数组 */ public static Boolean[] wrap(boolean... values) { final int length = values.length; Boolean[] array = new Boolean[length]; for (int i = 0; i < length; i++) { array[i] = values[i]; } return array; } /** * 判定给定对象是否为数组类型 * * @param obj 对象 * @return 是否为数组类型 */ public static boolean isArray(Object obj) { return obj.getClass().isArray(); } /** * Iterator转换为Enumeration * Adapt the specified Iterator to the Enumeration interface. * * @param iter Iterator * @return Enumeration */ public static Enumeration asEnumeration(final Iterator iter) { return new Enumeration() { @Override public boolean hasMoreElements() { return iter.hasNext(); } @Override public E nextElement() { return iter.next(); } }; } /** * Enumeration转换为Iterator
* Adapt the specified Enumeration to the Iterator interface * * @param e Enumeration * @return Iterator */ public static Iterator asIterator(final Enumeration e) { return new Iterator() { @Override public boolean hasNext() { return e.hasMoreElements(); } @Override public E next() { return e.nextElement(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy