这几天在看《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]最后,说说对重载的认识:一句话,能够使用重载的方法并不意味着应该使用重载。一般情况下,对于多个具有相同参数的方法来说,应该尽量避免使用重载方法。
针对同一组参数只须经过类型转变就可以传递给不同的重载方法的情况更要避免。