我正在使用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() );
答案 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按预期运行时,它会显示错误的名称。
不确定我为什么不早点注意到这一点。