1. 程式人生 > >TreeSet和TreeMap不能存放重復元素?能不能存放null?

TreeSet和TreeMap不能存放重復元素?能不能存放null?

null public 博文 .get 我們 正常 new tps 通過

問題一:本來認為TreeMap不能存放重復元素?其實並非如此;
其實一般情況下是不允許存放重復元素的,但是它並非這麽死板,在一些情況下是可以存放重復元素的,存了又會有引入其他問題。
問題二:能不能存放null呢?正常情況下是不能的,會報異常,但是經過一些處理後是可以的。
解答問題一:
1、存放元素時,TreeMap實現外部比較器接口Comparator,並重寫其compare方法,當判斷元素重復時,強制compare方法返回一個非0的數,就可以將重復元素存入;

TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
if(o1.equals(o2))
return 1;
else
return o1-o2;
}
});

這種是通過外部比較器進行排序,即是,不通過元素自身的方法來比較,而通過集合實現比較器接口來進行排序。上面代碼,通過外部比較器中重寫compare方法,判斷其返回值來確定排序位置,判斷結果有三種:(一)大於0,(二)小於0,(三)等於0;大於0時,表示o1比o2大,因此要排在後面,,小於0時,表示o1比o2小,因此要排在前面,等於0時,集合會認為二者相等,即已經存在此元素了,不再存儲(從這一點可以反映出TreeMap集合框架的防止元素重復的機制),但是會對值進行更新(我們的重點不在值)。~~這一點就體現了TreeMap集合的靈活性了,我們如果想存入重復元素,那麽就可以控制compare方法的返回值,來達到目的。這樣是有效的→→↓↓;
但是???問題來了,比如我們在compare中重寫,判斷兩個元素一樣是,強制返回1,元素是存進去了,可是我們在調用get方法去拿出這個元素和其值時,就出問題了,拿到的永遠是null,也就是找不到這個元素!不按常規出牌總是要付出代價的,為什麽呢??查看底層代碼,我們可以發現,get方法取元素同樣是根據比較器來取,調用compare方法查找,直到查找到能讓compare方法返回0的元素,就判斷,這個元素就是我們要找的元素,就將它的值取出來,如果查完了也沒有返回0,那麽就認為集合中不存在這個鍵,返回null!
Demo:

TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
if(o1.equals(o2))
return 1;
else
return o1-o2;
}
});
tree.put(1, "唐僧");
tree.put(2, "李白");
tree.put(5, "白居易");
tree.put(3, "孫悟空");
tree.put(2, "李黑");
System.out.println(tree);
System.out.println("get(1):"+tree.get(1)+" get(2)"+tree.get(2));

輸出:
{1=唐僧, 2=李白, 2=李黑, 3=孫悟空, 5=白居易}
get(1):null get(2)null

將compare方法中的equles判斷返回值改為0,輸出:
{1=唐僧, 2=李黑, 3=孫悟空, 5=白居易}
get(1):唐僧 get(2)李黑

同樣的道理,TreeSet其實就是通過TreeMap來實現的,那麽其也響應的特性。

—————————————————————————–
解答問題二:
能不能存放null呢?是可以存放的,但是要避免一個問題,避免出現空指針異常,這個問題是很容易出現的;
如果不實現Comparator接口,那麽一定會報出空指針異常(有人會問了,不是還可以用元素實現內部比較器接口嗎?是可以實現接口,但是實現了後,存入一個空元素也沒法調用它裏面的compareTo方法。。),如果實現了Comparator接口,通過適當的寫法,時可以避免出現空指針異常,並且順利的將元素存入和取出:

TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
if(o1 !=null&&o2!=null)
return o1-o2;
else if(o1 == null&&o2 != null){
return -1;
}else if(o1!=null&&o2==null)
return 1;
else
return 0;
}
});
tree.put(1, "唐僧");
tree.put(2, "李白");
tree.put(5, "白居易");
tree.put(3, "孫悟空");
tree.put(2, "李黑");
tree.put(null, "趙信");
System.out.println(tree);
System.out.println("get(1):"+tree.get(1)+" get(2)"+tree.get(null));

輸出:
{null=趙信, 1=唐僧, 2=李黑, 3=孫悟空, 5=白居易}
get(1):唐僧 get(2)趙信
---------------------
作者:TT海淺
來源:CSDN
原文:https://blog.csdn.net/u010698072/article/details/55255073
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

TreeSet和TreeMap不能存放重復元素?能不能存放null?