这可能是显而易见的事情,但无法合理化此代码段的输出。 参考:this
public class Sample {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
List<Integer> list = new ArrayList<Integer>();
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
System.out.println("After adding elements:");
System.out.println(set + " " + list);
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
System.out.println("After removing elements:");
System.out.println(set + " " + list);
}
}
输出:
添加元素后:
[ - 3,-2,-1,0,1,2] [-3,-2,-1,0,1,2]
删除元素后:
[ - 3,-2,-1] [-2,0,2]
我期待:
删除元素后:
[ - 3,-2,-1] [0,1,2]
即。 list.remove(i)实际应该删除列表中的第1,第2和第3项。公平吗?
答案 0 :(得分:6)
当您删除第一个元素时,您可以更改列表中元素的位置,因此代码的行为是有意义的:
e.g。
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
System.out.println("After adding elements:");
System.out.println(set + " " + list);
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
每次调用list.remove(i)时,列表会减少1个项目,项目位置向左移动:位置1的项目进入位置0,位置2的项目进入位置1等...
使用Iterator删除元素或List的clear方法。
如果要根据它的值删除Integer对象,请将int更改为Integer:
list.remove(Integer.valueOf(i));
答案 1 :(得分:3)
不,以下一行:
set.remove(i);
将您传递的int类型和box转换为Integer对象(see here),然后使用Integer equals()方法确定必须删除哪个元素。之所以会发生这种情况,是因为remove(int index)
的集合中没有这样的方法,只有remove(Object o)
,这意味着原始类型“不知何故”必须转换为Object,在Java中,每种基元类型都有一个Wrapper类型而“转换”被称为自动装箱。请注意,还有一种称为拆箱的“现象”:)。
答案 2 :(得分:1)
[-3, -2, -1, 0, 1, 2]
remove index 0
[-2, -1, 0, 1, 2]
remove index 1
[-2, 0, 1, 2]
remove index 2
[-2, 0, 2]
列表中的位置随每次删除而变化。只需移除位置'0'的3倍。
答案 3 :(得分:1)
如果是Set
,您指定的是the object to remove,因此实际上会移除值 0
,1
和2
从集合。因此,您将获得剩余的元素。
如果是List
,您指定the index of object to remove,因此实际会删除索引 0
,1
和{{1从列表中。因此,您将获得剩余的元素。它的工作原理如下:
2
答案 4 :(得分:0)
曾经想过用功能编程方式吗?
//确保为matcher和lambdaj添加静态导入以模拟以下代码
import static ch.lambdaj.Lambda.*;
import static org.test.matcher.MatcherFactory.*; //this can be anything
List<Integer> original = Arrays.asList(1,2,3,4,5,6);
List<Integer> oddList = filter(odd, original);
for(int s : oddList){
System.out.println(s);
}
//and it prints out 1,3,5
创建一个名为MatcherFactory.java的类
public class MatcherFactory {
public static Matcher<Integer> odd = new Predicate<Integer>() {
public boolean apply(Integer item) {
return item % 2 == 1;
}
};
//put as many as matchers you want and reuse them
}
您可以从这里下载lambdaj库
https://code.google.com/p/lambdaj/wiki/LambdajFeatures
并查看更多示例