这是我刚刚遇到的一个很好的陷阱。考虑整数列表:
List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);
对你执行时会发生什么有根据的猜测吗 list.remove(1)
? 那么...怎么样 list.remove(new Integer(1))
? 这会引起一些讨厌的虫子。
区分两者的正确方法是什么 remove(int index)
,它从给定的索引和 remove(Object o)
,它在处理整数列表时通过引用删除元素?
这里要考虑的要点是尼基塔提到的,精确的参数匹配优先于自动装箱。
8条答案
按热度按时间nhjlsmyf1#
java总是调用最适合您的论点的方法。只有在没有强制转换/自动强制转换的情况下,无法调用任何方法时,才会执行自动强制转换和隐式向上转换。
列表接口指定了两种删除方法(请注意参数的命名):
remove(Object o)
remove(int index)
也就是说list.remove(1)
删除位置1处的对象,然后单击“确定”remove(new Integer(1))
从此列表中删除指定元素的第一个匹配项。2fjabf4q2#
你可以使用铸造
和
不管n是int还是integer,该方法总是调用您期望的方法。
使用
(Integer) n
或Integer.valueOf(n)
它的效率比new Integer(n)
因为前两个可以使用整数缓存,而后一个将始终创建一个对象。r1zhe5dt3#
我不知道“适当”的方式,但你建议的方式很好:
移除给定位置处的元素并
从列表中删除给定对象。
这是因为vm首先尝试查找使用完全相同的参数类型声明的方法,然后才尝试自动装箱。
jaxagkaj4#
list.remove(4)
完全符合list.remove(int index)
,所以它将被称为。如果你想打电话list.remove(Object)
请执行以下操作:list.remove((Integer)4)
.envsm3lx5#
对执行列表时发生的情况有任何有根据的猜测。删除(1)?那么list.remove(新的整数(1))呢?
没有必要猜测。第一个案例将导致
List.remove(int)
正在调用,并且元素位于1
将被删除。第二种情况将导致List.remove(Integer)
正在调用,且其值等于Integer(1)
将被删除。在这两种情况下,java编译器都会选择最接近的匹配重载。是的,这里有可能出现混淆(和bug),但这是一个相当罕见的用例。
当这两个
List.remove
方法是在Java1.2中定义的,重载并不含糊。这个问题只是在Java1.5中引入泛型和自动装箱之后才出现的。事后看来,如果其中一个remove方法被赋予不同的名称会更好。但现在已经太晚了。x9ybnkn66#
请注意,即使虚拟机没有做正确的事情,您仍然可以使用以下事实来确保正确的行为:
remove(java.lang.Object)
对任意对象进行操作:g9icjywg7#
正如#decitrig在接受回答第一条评论中所建议的那样,我只是喜欢以下内容。
这对我有帮助。再次感谢您的评论。这可能对某些人有帮助。
ugmeyewa8#
好吧,这就是诀窍。
让我们举两个例子:
现在让我们看看输出:
现在让我们分析一下输出:
从集合中删除3时,它将调用
remove()
采取的收集方法Object o
作为参数。因此,它会删除对象3
. 但在arraylist对象中,它被索引3覆盖,因此第4个元素被删除。通过相同的对象删除逻辑,在两种情况下,在第二个输出中都会删除null。
所以要去掉这个数字
3
这是一个我们需要明确传递3作为object
.这可以通过使用wrapper类进行强制转换或 Package 来实现
Integer
.如: