Java--如何高效向List中存放不重復的數據(附帶時間測試)


set不允許出現重復的值(key)

List是不能存儲重復數據的,而我們想利用List存儲不重復的元素,一般都使用List自帶的contains方法對元素進行判斷,如果不包含再進行添加,但是這樣太耗時了。

含再進行添加,但是這樣太耗時了。

    if (!list.contains("/home/" + i)) {
        list.add("/home/" + i);
    }

其實我們可以利用set集合存儲元素的去重特性來進行list的去重存儲,如果set能添加,list就進行添加。

    if (set.add("/home/" + i)) {
        list.add("/home/" + i);
    }


下面我們就來測試幾種向List存放不重復數據方法的耗時情況:

    public class Test {
     
        public static List<String> list = new ArrayList<String>();
        public static Set<String> set = new HashSet<>();
        public static Set<String> sortset = new LinkedHashSet<>();
     
        public static void main(String[] args) {
            // 利用Hashset去重的特性
            long s1 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                if (set.add("/home/" + i)) {
                    list.add("/home/" + i);
                }
            }
            System.out.println("使用Hashset進行list去重速度:" + (System.currentTimeMillis() - s1));
     
            // 利用linkedHashSet去重且存放有序的特性
            long s4 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                if (sortset.add("/home/" + i)) {
                    list.add("/home/" + i);
                }
            }
            System.out.println("使用LinkedHashset進行list去重速度:" + (System.currentTimeMillis() - s4));
     
            // 利用list自帶contains方法做判斷
            long s2 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                if (!list.contains("/home/" + i)) {
                    list.add("/home/" + i);
                }
            }
     
            System.out.println("使用lists的contain方法去重速度:" + (System.currentTimeMillis() - s2));
     
            // 先存到HashSet,再將全部元素添加到list中
            long s3 = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                set.add("/home/" + i);
            }
            list.addAll(set);
            System.out.println("使用set去重,然后添加到list中速度:" + (System.currentTimeMillis() - s3));
     
        }
     
    }


測試結果如下圖:



經過觀察我們可以發現,這其中先使用set進行去重,然后再將set所有元素添加到list中是最快的。但是需要注意的是,List的addAll()方法默認是會將要添加集合的元素添加到list的尾部,如果你的這個list中本身包含了其他數據,添加時對順序有要求的話要謹慎使用。最好是使用第一種方式,使用set是否可以添加作為判斷條件,這樣在這個過程中還可以附帶其他條件。比較靈活。
而使用List的contains方法則耗時最久,與其他方式速度相差幾十倍。所以大家以后還是盡量不要使用contains來進行去重的判斷了。

Set集合是沒有重復數據的特性,那么對於元素為對象 的情況是否也同樣奏效?

參看:https://www.cnblogs.com/interdrp/p/12324738.html

判斷插入的key是否存在,要判斷兩點①hash值是否相同;②對應的值是否相同,前者要看hashCode()方法,后者要看equal()方法。

1)只要重寫equals,就必須重寫hashCode;

2)因為Set存儲的是不重復的對象,依據hashCode和equals進行判斷,所以Set存儲的對象必須重寫這兩個方法。

3)如果自定義對象做為Map的鍵,那么必須重寫hashCode和equals。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM