比较两个集合是否相等

如题,怎么比较两个集合是否相等呢?比如:

List listA = {1,1,2,3,4}

List listB = {1,2,3,4,5}

思路一:

1、首先,两个集合的长度必须要一样,一个长度是3,一个是4,那两个集合必然不相等;

2、listA  要包含  listB 里面的每一个元素

3、listB  要包含  listA 里面的每一个元素

代码实现:

    /**
     * 比较两个集合是否相等
     * @param a
     * @param b
     * @return
     */
    public static boolean isEqualCollection(final Collection a, final Collection b) {
        if (a.size() != b.size()) {
            return false;
        }
        for (Iterator ita = a.iterator(); ita.hasNext(); ) {
            if (!b.contains(ita.next())) {
                return false;
            }
        }
        for (Iterator itb = b.iterator(); itb.hasNext(); ) {
            if (!a.contains(itb.next())) {
                return false;
            }
        }
        return true;
    }

测试:

public static void main(String[] args) {
        List<Integer> lista = Arrays.asList(1, 1, 2, 3, 4);
        List<Integer> listb = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> listc = Arrays.asList(2, 1, 4, 3, 1);
        boolean equalCollectionAB = isEqualCollection(lista, listb);
        System.out.println("A和B是否相等:" + equalCollectionAB);
        boolean equalCollectionAC = isEqualCollection(lista, listc);
        System.out.println("A和C是否相等:" + equalCollectionAC);
    }

结果:

总结:

两个集合相互遍历,利用contains方法,确保两个集合 你中有我,我中有你,且长度相同

但是如果两个集合中的数据量较大时,遍历的话,复杂度就是O(n),我们下面来测试一下,A、B两个集合,各有十万条数据

public static void main(String[] args) {
        List<Integer> lista = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            lista.add(i);
        }
        List<Integer> listb = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            listb.add(i);
        }
        long start = System.currentTimeMillis();
        boolean equalCollection = isEqualCollection(lista, listb);
        long cost = System.currentTimeMillis() - start;
        System.out.println("A和B是否相等:" + equalCollection + ",耗时:" + cost + "ms");
    }

测试结果为:

还是蛮耗时的,需要五六秒的时间

思路二:

1、首先,两个集合的长度必须要一样,一个长度是3,一个是4,那两个集合必然不相等;

2、listA 里面的每个元素都在listB里,且元素的个数相同

 代码实现:

public static boolean isEqualCollectionFast(final Collection a, final Collection b) {
        if (a.size() != b.size()) {
            return false;
        }
        Map mapa = getMap(a);
        Map mapb = getMap(b);

        if (mapa.size() != mapb.size()) {
            return false;
        }

        Iterator it = mapa.keySet().iterator();

        while (it.hasNext()) {
            Object obj = it.next();
            if (getFreq(obj, mapa) != getFreq(obj, mapb)) {
                return false;
            }
        }
        return true;
    }


private static Integer INTEGER_ONE = new Integer(1);


    /**
     * 集合转map,值就是key出现的次数
     *
     * @param coll
     * @return
     */
    public static Map getMap(final Collection coll) {
        Map count = new HashMap();
        Iterator it = coll.iterator();
        while (it.hasNext()) {
            Object obj = it.next();
            Integer c = (Integer) (count.get(obj));
            if (null == c) {
                count.put(obj, INTEGER_ONE);
            } else {
                count.put(obj, new Integer(c.intValue() + 1));
            }
        }
        return count;
    }

    /**
     * 获取map的值(频率)
     *
     * @param obj
     * @param freqMap
     * @return
     */
    private static final int getFreq(final Object obj, final Map freqMap) {
        Integer count = (Integer) freqMap.get(obj);
        if (null == count) {
            return 0;
        }
        return count.intValue();
    }

测试:

public static void main(String[] args) {
        List<Integer> lista = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            lista.add(i);
        }
        List<Integer> listb = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            listb.add(i);
        }
        long start = System.currentTimeMillis();
        boolean equalCollection = isEqualCollectionFast(lista, listb);
        long cost = System.currentTimeMillis() - start;
        System.out.println("快速比较-A和B是否相等:" + equalCollection + ",耗时:" + cost + "ms");
    }

测试结果为:

发现换了一种写法,两个十万数据量的集合作比较,性能提升了185倍。所以我们平时开发过程中,要善于使用一级缓存、二级缓存等来帮助我们提高性能。

下面是不同数据量的情况,两种写法的性能比较

 
      条数\时间                      一般                         快速                         倍数
100 0ms 0ms ----
1000 6ms 1ms 6倍
10000 62ms 8ms 8倍
100000 5794ms 25ms

231倍

发布了165 篇原创文章 · 获赞 103 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/qq_33101675/article/details/102480026