在以下示例中:
public static void main(String[] args){
List<String> list = new ArrayList<String>();
list.add("hi");
list.add("hi");
list.add("hi");
list.remove("hi");
System.out.println(list); //prints [hi, hi]
}
ArrayList减少了一个但删除了哪一个?它是删除最后插入的还是最早插入的?
答案 0 :(得分:7)
来自docs - Removes the first occurrence of the specified element from this list, if it is present.
答案 1 :(得分:4)
由于记录了List#add()
要添加到列表的 end ,并且记录了List#remove(Object)
以返回它遇到的第一个匹配项,您的上述调用将删除最早插入的字符串“hi”的实例。
由于列表中三个对象的打印表示都是相同的,因此很难看到行为的差异。但是,如果您查看调试器中的实例地址,并注意哪个实例地址首先进入列表,您将确认它也是第一个也是唯一一个要删除的地址。
在你的情况下,假设你正在使用字符串文字,它们是由编译器实习(每§3.10.5 of the JLS),所以你会看到三个相同实例出现在您的列表中。要生成不同的String
实例,请尝试将三个插入调用更改为以下内容:
/* not final */ String h = "h";
list.add(h + "i"); // not interned, instance 1
list.add(h + "i"); // not interned, instance 2
list.add(h + "i"); // not interned, instance 3
将您在调试器中看到的内容与原始程序进行比较。你看到了不同吗?
请注意,如果上面的String
实例h
被声明为 final ,那么这三个连接实际上都会被实习,产生将相同的 String
实例添加到列表中三次。感谢@xehpuk纠正我关于最终限定符的初始错误。
答案 2 :(得分:2)
它将删除它遇到的第一个出现,所以你添加的第一个出现。