這幾天在看《Effective Java》這本書,在第41條--慎用重載這一章中發現一個平時沒注意的問題。
先看例子:
public static void main(String[] args) {Set<Integer> set = new TreeSet<Integer>();List<Integer> list = new ArrayList<Integer>(); for(int i=0;i<10;i++) { set.add(i); list.add(i); } System.out.println(set + " " + list); for(int i =0;i<5;i++) { set.remove(i); list.remove(i); } System.out.println(set + " "+ list);} 期望的輸出結果是:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][5, 6, 7, 8, 9] [5, 6, 7, 8, 9]
但是真實的輸出結果是:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][5, 6, 7, 8, 9] [1, 3, 5, 7, 9]
這是為什麼呢。主要是因為:
set.remove(i)調用重載方法remove(E),這裡的E是集合(Integer)類型,使用時將i自動裝箱為Integer,得到的結果也這是我們所期待的的內容。
list.remove(i)調用的重載方法remove(int i)它是從列表指定的位置去除元素。
列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],首先去除第0個元素得到[1, 2, 3, 4, 5, 6, 7, 8, 9]
接著去除第1個元素得到[1, 3, 4, 5, 6, 7, 8, 9],以此類推,最終得到[1, 3, 5, 7, 9]
問題的找到了,那麼接下來說說如何解決問題,其實很簡單,只需要把list.remove的參數轉換成Integer就好了,先看代碼:
public static void main(String[] args) {Set<Integer> set = new TreeSet<Integer>();List<Integer> list = new ArrayList<Integer>(); for(int i=0;i<10;i++) { set.add(i); list.add(i); } System.out.println(set + " " + list); for(int i =0;i<5;i++) { set.remove(i); list.remove((Integer)i); } System.out.println(set + " "+ list);} 輸出的結果為:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][5, 6, 7, 8, 9] [5, 6, 7, 8, 9]
最後,說說對重載的認識:一句話,
能夠使用重載的方法並不意味著應該使用重載。一般情況下,對於多個具有相同參數的方法來說,應該盡量避免使用重載方法。
針對同一組參數只須經過類型轉變就可以傳遞給不同的重載方法的情況更要避免。