Java基础干货Guava集合工具CollectionUtil源码剖析

Posted 在路上的德尔菲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础干货Guava集合工具CollectionUtil源码剖析相关的知识,希望对你有一定的参考价值。

CollectionUtils

应用

public class CollectionUtilsGenTest {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<String>(){
            {
                add("duffy");
                add("wang");
                add("seu");
            }
        };
        ArrayList<String> list2 = new ArrayList<String>() {
            {
                add("luffy");
                add("wang");
                add("pku");
            }
        };
        // isNotEmpty 判断集合是否不为空,对比isEmpty 结果相反
        boolean notEmpty = CollectionUtils.isNotEmpty(list1);
        //---------- true -------------

        // get 得到集合索引的对象
        Object res = CollectionUtils.get(list1, 0);
        //---------duffy ---------------
		
		 //addAll 
        CollectionUtils.addAll(list1,list2.iterator());
        // ---list = [duffy, wang, seu, luffy, wang, pku] ---

        // union 两个集合的并集
        Collection union = CollectionUtils.union(list1, list2);
        //----- [seu, wang, luffy, pku, duffy]-----------

        // intersection 两个集合的交集
        Collection intersection = CollectionUtils.intersection(list1, list2);
        //--------- [wang] -------------

        // isEqualCollection 判断两个集合是否相同
        boolean equalCollection = CollectionUtils.isEqualCollection(list1, list2);
        //----------- false ------------
    }
}
public class CollectionUtilsTest {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>() {
            {
                add(1);
                add(2);
                add(3);
                add(4);
            }
        };
        
        //--------filter  过滤掉不符合的数据--------
        CollectionUtils.filter(arrayList, o -> Integer.valueOf(o.toString()) > 4);
        //-------1 -> [2,3,4]   4 -> []------

        //--------select  把符合的数据重新组成一个集合,对比filter--------
        Collection collection = CollectionUtils.select(arrayList, o -> Integer.valueOf(o.toString()) > 4);
        //--------1-> [2,3,4]  4 -> []----------

        //--------countMatch 集合中符合规则的数据个数--------
        int count = CollectionUtils.countMatches(arrayList, o -> Integer.valueOf(o.toString()) > 4);
        //--------1 -> 3  4 -> 0 ------------

        //--------exists  集合中是否存在符合规则的数据--------
        boolean exists = CollectionUtils.exists(arrayList, o -> Integer.valueOf(o.toString()) > 4);
        //--------1 -> true   4 -> false-------

        //--------find  注意只返回一个符合的规则数据--------
        Object result = CollectionUtils.find(arrayList, o -> Integer.valueOf(o.toString()) > 4);
        //--------1-> 2   4 -> null-----------
    }
}

源码

isNotEmpty

    public static boolean isNotEmpty(Collection coll) {
        return !isEmpty(coll);
    }

addAll

    public static void addAll(Collection collection, Iterator iterator) {
        while(iterator.hasNext()) {
            collection.add(iterator.next());
        }
    }

    public static void addAll(Collection collection, Enumeration enumeration) {
        while(enumeration.hasMoreElements()) {
            collection.add(enumeration.nextElement());
        }
    }

    public static void addAll(Collection collection, Object[] elements) {
        int i = 0;

        for(int size = elements.length; i < size; ++i) {
            collection.add(elements[i]);
        }
    }

IteratorEnumerationObject[]三种类型各有各的add方式,因此需要分开写

get

    public static Object get(Object object, int index) {
        if (index < 0) {
            throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
        } else if (object instanceof Map) {
            Map map = (Map)object;
            Iterator iterator = map.entrySet().iterator();
            return get(iterator, index);
        } else if (object instanceof List) {
            return ((List)object).get(index);
        } else if (object instanceof Object[]) {
            return ((Object[])((Object[])object))[index];
        } else {
            Iterator it;
            if (object instanceof Iterator) {
                it = (Iterator)object;

                while(it.hasNext()) {
                    --index;
                    if (index == -1) {
                        return it.next();
                    }

                    it.next();
                }

                throw new IndexOutOfBoundsException("Entry does not exist: " + index);
            } else if (object instanceof Collection) {
                it = ((Collection)object).iterator();
                return get(it, index);
            } else if (object instanceof Enumeration) {
                Enumeration it = (Enumeration)object;

                while(it.hasMoreElements()) {
                    --index;
                    if (index == -1) {
                        return it.nextElement();
                    }
                    it.nextElement();
                }
                throw new IndexOutOfBoundsException("Entry does not exist: " + index);
            } else if (object == null) {
                throw new IllegalArgumentException("Unsupported object type: null");
            } else {
                try {
                    return Array.get(object, index);
                } catch (IllegalArgumentException var4) {
                    throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
                }
            }
        }
    }

**考虑的很严谨,很值得学习,**其中Map类型很有意思,map.entrySet().iterator()再进行一次get操作,和set做一样的操作;else if (object instanceof Collection)我是没有想到:),还有IndexOutOfBoundsExceptionIllegalArgumentException异常情况需要考虑

union

    public static Collection union(Collection a, Collection b) {
        ArrayList list = new ArrayList();
        Map mapa = getCardinalityMap(a);
        Map mapb = getCardinalityMap(b);
        Set elts = new HashSet(a);
        elts.addAll(b);
        Iterator it = elts.iterator();

        while(it.hasNext()) {
            Object obj = it.next();
            int i = 0;
            for(int m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
                list.add(obj);
            }
        }
        return list;
    }

union 循环函数中为Math.max(getFreq(obj, mapa), getFreq(obj, mapb))

 for(int m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
            list.add(obj);
  }

其中这段代码很有意思,m取两个Collection中相同对象出现的最多次数,注意,如果比如Collection a中有重复的,是不会去重的,只是取并集,没有单独对一个Collection中元素去重

intersection

    public static Collection intersection(Collection a, Collection b) {
        ArrayList list = new ArrayList();
        Map mapa = getCardinalityMap(a);
        Map mapb = getCardinalityMap(b);
        Set elts = new HashSet(a);
        elts.addAll(b);
        Iterator it = elts.iterator();

        while(it.hasNext()) {
            Object obj = it.next();
            int i = 0;

            for(int m = Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
                list.add(obj);
            }
        }

        return list;
    }

intersection循环函数中为Math.min(getFreq(obj, mapa), getFreq(obj, mapb))m取两个Collection中出现的最少次数,那么list也就add最少的次数,为取交集功能,同上union,并没有去重的意思。

isEqualCollection

    public static boolean isEqualCollection(Collection a, Collection b) {
        if (a.size() != b.size()) {
            return false;
        } else {
            Map mapa = getCardinalityMap(a);
            Map mapb = getCardinalityMap(b);
            if (mapa.size() != mapb.size()) {
                return false;
            } else {
                Iterator it = mapa.keySet().iterator();

                Object obj;
                do {
                    if (!it.hasNext()) {
                        return true;
                    }

                    obj = it.next();
                } while(getFreq(obj, mapa) == getFreq(obj, mapb));

                return false;
            }
        }
    }

Collection.size():Returns the number of elements in this collection,map.size():Returns the number of key-value mappings in this map,如果不相同直接返回false,然后对每一个对象在Collection出现的次数是否相等,所以对Collection中顺序没有关系。比如list1[“seu”,“duffy”,“wang”,“seu”]和list2[“wang”,“seu”,“seu”,“duffy”]是isEqualCollection返回是true的。

getCardinalityMap
    public static Map getCardinalityMap(Collection coll) {
        Map count = new HashMap();
        Iterator it = coll.iterator();

        while(it.hasNext()) {
            Object obj = it.next();
            Integer c = (Integer)((Integer)count.get(obj));
            if (c == null) {
                count.put(obj, INTEGER_ONE);
            } else {
                count.put(obj, new Integer(c + 1));
            }
        }

        return count;
    }

Cardinality翻译为基数,这个逻辑经常在HashMap的逻辑中看到,统计相同的key出现的次数,然后返回这样一个map。

getFreq
    private static final int getFreq(Object obj, Map freqMap) {
        Integer count = (Integer)freqMap.get(obj);
        return count != null ? count : 0;
    }

getCardinalityMap中key对应出现的次数。

filter

    public static void filter(Collection collection, Predicate predicate) {
        if (collection != null && predicate != null) {
            Iterator it = collection.iterator();

            while(it.hasNext()) {
                if (!predicate.evaluate(it.next())) {
                    it.remove();
                }
            }
        }
    }

select

    public static Collection select(Collection inputCollection, Predicate predicate) {
        ArrayList answer = new ArrayList(inputCollection.size());
        select(inputCollection, predicate, answer);
        return answer;
    }

    public static void select(Collection inputCollection, Predicate predicate, Collection outputCollection) {
        if (inputCollection != null && predicate != null) {
            Iterator iter = inputCollection.iterator();

            while(iter.hasNext()) {
                Object item = iter.next();
                if (predicate.evaluate(item)) {
                    outputCollection.add(item);
                }
            }
        }
    }

countMatches

    public static int countMatches(Collection inputCollection, Predicate predicate) {
        int count = 0;
        if (inputCollection != null && predicate != null) {
            Iterator it = inputCollection.iterator();

            while(it.hasNext()) {
                if (predicate.evaluate(it.next())) {
                    ++count;
                }
            }
        }
        return count;
    }

exists

    public static boolean exists(Collection collection, Predicate predicate) {
        if (collection != null && predicate != null) {
            Iterator it = collection.iterator();

            while(it.hasNext()) {
                if (predicate.evaluate(it.next())) {
                    return true;
                }
            }
        }
        return false;
    }

find

    public static Object find(Collection collection, Predicate predicate) {
        if (collection != null && predicate != null) {
            Iterator iter = collection.iterator();

            while

以上是关于Java基础干货Guava集合工具CollectionUtil源码剖析的主要内容,如果未能解决你的问题,请参考以下文章

Java基础干货Guava CacheBuilder源码剖析

别再重复造轮子了,推荐使用 Google Guava 开源工具类库,真心强大!

有没有一种优雅的方法可以在使用 Guava 转换集合时删除空值?

集合-强大的集合工具类:java.util.Collections中未包含的集合工具

java代码之美---guava之Immutable(不可变)集合

java基础--extension package guava