17

鉴于下面的代码,是否可以p在 Java 中使用这种 for 循环样式从属性列表中删除索引?

List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";

for(Properties p : propertiesList) {
    if(p.getKey().equals(keyToDelete)) {
        propertiesList.remove(index) //How to remove the element at index 'p'
    }
}

这就是我如何用另一个for循环来完成这个

List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";

for(int i = 0; i < propertiesList.size(); i++) {
        if(p.getKey().equals(keyToDelete)) {
                propertiesList.remove(i);
        }
}
4

5 回答 5

27

做到这一点的方法是明确的Iterator(没有像老派那样的学校!)。

Iterator<Properties> it = propertiesList.iterator();
while (it.hasNext()) {
    if (it.next().getKey().equals(keyToDelete)) {
        it.remove();
    }
}

与列表上的 remove 方法不同,remove迭代器上的方法不会导致并发修改。这是从您正在迭代的集合中删除元素的唯一安全方法。正如该方法的 javadoc 所说:

如果在迭代过程中以除调用此方法之外的任何方式修改了底层集合,则迭代器的行为是未指定的。

于 2012-07-19T15:40:29.740 回答
8

不,您需要使用老式的 for 循环来获取索引。

您当然可以自己将其添加到 for-each 循环中,但是使用旧变体可能会更好。

于 2012-07-19T15:35:25.487 回答
8

如何使用正确Iteratorremove方法?

List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";

for (
    Iterator<Properties> iter = propertiesList.iterator( );
    iter.hasNext( );
)
{
    Properties p = iter.next( );

    if(p.getKey().equals(keyToDelete)) {
        iter.remove( );
    }
}
于 2012-07-19T15:40:51.910 回答
2

正如蒂姆安德森建议的那样,您还可以在循环外修改列表

List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";
List<Properties> propertiesToRemove = new ArrayList<Properties>();


for(Properties p : propertiesList) {
    if(p.getKey().equals(keyToDelete)) {
        propertiesToRemove.add(p) ;
    }
}

propertiesList.removeAll(propertiesToRemove);
于 2012-07-19T15:45:29.240 回答
1

据我所知,foreach 循环不保证它枚举的元素的顺序,

因此,如果您尝试 Collection[i],您可以获得另一个元素,而不是当前迭代

在一些多线程的情况下可以清楚的看到

于 2012-07-19T15:40:22.580 回答