轉載本文章請標明作者和出處
本文出自愛喝純淨水的南榮牧歌
緣起
上週,我做了成都一個著名中學的考勤項目,其中裏面有一個排行榜的功能,我就是用了TreeSet進行排序,最後發現排序前後莫名其妙的少了幾個元素,當時我還沒有發現,後來被測試小姐姐提成了BUG;
追溯
然後我就寫了一個Demo來驗證整個問題;
-
代碼
TreeSet<Integer> set = new TreeSet<>(); set.add(7); set.add(2); set.add(1); set.add(1); for (Integer integer : set) { System.out.println(integer); }
-
輸出
果然,和預想的沒有錯,只要兩個元素相同就會被覆蓋掉,然後我們再自定義一個比較器試試看; -
代碼
TreeSet<Integer> set = new TreeSet<>(((o1, o2) -> { if (o1 > o2) { return 1; } else if (o1 < o2) { return -1; } else { return 0; } } )); set.add(7); set.add(2); set.add(1); set.add(1); for (Integer integer : set) { System.out.println(integer); }
-
輸出
結果還是少了一個,這時我就考慮是不是因爲兩個元素比較後返回0那麼就只會保留一個呢?於是我們稍微的改一下比較器; -
代碼
TreeSet<Integer> set = new TreeSet<>(((o1, o2) -> { if (o1 > o2) { return 1; } else { return -1; } } )); set.add(7); set.add(2); set.add(1); set.add(1); for (Integer integer : set) { System.out.println(integer); }
-
輸出
-
結論
我們在使用TreeSet進行排序的時候,如果不希望元素被覆蓋,那麼相當的時候就要隨便的返回一個正數或者負數,絕對不能返回0;
因爲TreeSet的底層即爲TreeMap,所以我們使用TreeMap進行排序的時候同理;
通過查看源碼的時候我們發現,如果返回0的元素會直接找到同樣的一個樹節點,並把原來的值幹掉;