Java集合接口动态分派

huangapple go评论68阅读模式
英文:

Java Collections Interface Dynamic Dispatch

问题

Collection<Integer> list = new ArrayList<>();
list.add(0);
list.add(1);
list.add(2);

for (int i = 0; i < 3; i++) {
  list.remove(i);
}
System.out.println(list);
  }
}

我的问题:
为什么列表使用 remove(object o) 而不是 ArrayList.remove(int index)?我以为在编译时,列表会知道实际对象(动态类型)(ArrayList 的方法),而不是超类的方法。

英文:
Collection&lt;Integer&gt; list = new ArrayList&lt;&gt;();
list.add(0);
list.add(1);
list.add(2);

for (int i = 0; i &lt; 3; i++) {
  list.remove(i);
}
System.out.println(list);
  }

}

My Question:
Why does the list uses remove(object o) rather than ArrayList.remove (int index). I thought during compile time, list would what the actual object (dynamic type) (Arraylist's methods) not the superclass's methods.

答案1

得分: 2

这会执行 remove(Object),因为你的 list 变量的类型是 Collection,而且 Collection 并没有指定 remove(int index) 方法。

编译器只会查看变量的编译时类型(Collection),而不会考虑对象的运行时类型(ArrayList)。

英文:

This executes remove(Object) because your list variable is of type Collection, and Collection does not specify a remove(int index) method.

The compiler is only looking at the compile-time type of the variable (Collection), not the runtime type of the object (ArrayList).

答案2

得分: 0

由于`list`声明为`Collection<Integer>`,所以调用了`Collection`的方法
```java
Collection<Integer> list = new ArrayList<>();
list.add(2);
list.add(1);
list.add(0);

for (int i = 0; i < 3; i++) {
  list.remove(i);
  System.out.println("after remove " + i + " -> " + list);
}

输出:

after remove 0 -> [2, 1]
after remove 1 -> [2]
after remove 2 -> []

同时,通过索引从ArrayList中删除元素并同时递增索引,这样做容易出错:

list.add(2);
list.add(1);
list.add(0);

List<Integer> lst = (List<Integer>) list;
System.out.println(lst);
for (int i = 0; i < 3; i++) { // 固定大小
  lst.remove(i); // Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 1
  System.out.println("after remove from list " + i + " -> " + lst);
}
英文:

Since list is declared as Collection&lt;Integer&gt;, then the methods of Collection are called.

Collection&lt;Integer&gt; list = new ArrayList&lt;&gt;();
list.add(2);
list.add(1);
list.add(0);

for (int i = 0; i &lt; 3; i++) {
  list.remove(i);
  System.out.println(&quot;after remove &quot; + i + &quot; -&gt; &quot; + list);
}

output:

after remove 0 -&gt; [2, 1]
after remove 1 -&gt; [2]
after remove 2 -&gt; []

Also it'd error-prone to remove an element from the ArrayList by index and keep incrementing the index at the same time:

list.add(2);
list.add(1);
list.add(0);

List&lt;Integer&gt; lst = (List&lt;Integer&gt;) list;
System.out.println(lst);
for (int i = 0; i &lt; 3; i++) { // size fixed
  lst.remove(i); // Exception in thread &quot;main&quot; java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 1
  System.out.println(&quot;after remove from list &quot; + i + &quot; -&gt; &quot; + lst);
}

答案3

得分: 0

由于您的列表是Collection,而Collection没有remove(int index)方法,但有remove(Object o)方法,因此使用remove(Object o)来进行移除操作。

当您将Collection更改为java.util.List,如下所示,移除操作将类似于remove(int index)的效果。

List<Integer> list = new ArrayList<>();
list.add(0);
list.add(1);
list.add(2);

for (int i = 0; i < 3; i++) {
    list.remove(i); // 尽管预期会出现IndexOutOfBoundsException
}
System.out.println(list);
英文:

Since your list is Collection and Collection does not have remove(int index) but has remove(Object o), remove is remove(Object o).

When you change Collection to java.util.List like below, remove works like remove(int index).

List&lt;Integer&gt; list = new ArrayList&lt;&gt;();
list.add(0);
list.add(1);
list.add(2);

for (int i = 0; i &lt; 3; i++) {
    list.remove(i); // IndexOutOfBoundsException expected though
}
System.out.println(list);

huangapple
  • 本文由 发表于 2020年10月7日 22:36:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/64246397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定