ArrayList访问应该删除的元素

时间:2011-02-10 22:22:40

标签: java arraylist

我正在使用Java进行数据挖掘项目,并且遇到了一个奇怪的ArrayList问题。

ArrayList(availAttribs)包含决策树当前分支中尚未使用的所有属性的名称。在循环开始时,选择一个属性,并将ArrayList中该属性的索引存储在selectedAttribute中。执行逻辑,然后从列表中删除项目,并选择另一个项目。

程序没有按预期运行,因此我在每个属性选择之前使用a for each循环显示ArrayList的当前内容,以便检查内容。

这就是我得到的:

availAttribs contains ...
-Color
-size
-act
-age
Chose attribute #1: size

availAttribs contains ...
-Color
-act
-age
Chose attribute #1: size

随机选择属性:

for(String s : availAttribs) {
   System.out.println("   -" + s); 
}   
chosenAttribute = random.nextInt(availAttribs.size() - 1); 
System.out.println("   Chose attribute #" + chosenAttribute + ": " +
      trainSet.attribute(chosenAttribute).name());

// other stuff here

availAttribs.remove(chosenAttribute);

所有这些都在while循环中检查退出条件。我认为,如果一个项目没有成功删除,当我遍历列表并打印每个元素时它会显示出来,但显然它仍然可以访问它们。

编辑: 随机声在while循环之外声明:

Random random = new Random(System.currentTimeMillis() );

3 个答案:

答案 0 :(得分:1)

ArrayList.remove(Obj)删除服从obj.equals(Obj)的第一个(最低索引)对象。你在索引上调用删除:

availAttribs.remove(chosenAttribute);

应该是

availAttribs.remove(availAttribs.get(chosenAttribute));

即。索引i的元素值而不是i;

答案 1 :(得分:0)

我的猜测 - 您在Integer对象上调用List.remove(...),而不是int原语。 chosenAttribute变量的类型是什么?

使用对象调用remove(...)命中remove(object)方法,例如:

Integer chosenAttribute = ...
availAttribs.remove(chosenAttribute);

将永远循环,但是:

int chosenAttribute = ...
availAttribs.remove(chosenAttribute);

按预期终止。

您可以获取索引的int原语并调用List.remove(int),或者您可以在索引处获取对象并调用List.remove(object)。要么应该工作。

答案 2 :(得分:0)

我在尝试解释部分代码以回应评论时想出了答案。 selectedAtrribute是关于ArrayList的索引,由于我填充ArrayList的方式,它对应于我在内部使用的数据结构分配给每个属性的索引。当我从ArrayList中删除一个项目后,它向前滑动所有的项目,它们不再同步。

由于我的调试语句是从数据结构中获取名称而不是从ArrayList本身获取名称,因此当arraylist按预期运行时,它会显示错误的名称。

不确定我为什么不早点注意到这一点。