mab*_*zer 79 java collections concurrency
我有以下代码:
private String toString(List<DrugStrength> aDrugStrengthList) {
StringBuilder str = new StringBuilder();
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}
str.append(aDrugStrengthList);
if (str.indexOf("]") != -1) {
str.insert(str.lastIndexOf("]"), "\n " );
}
return str.toString();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行它时,我得到ConcurrentModificationException,任何人都可以解释它为什么会发生,即使代码在同一个线程中运行?我怎么能避免它呢?
Kon*_*rus 162
如果您使用"for each"循环浏览它,则无法从列表中删除.你可以用Iterator.更换:
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
aDrugStrengthList.remove(aDrugStrength);
}
}
Run Code Online (Sandbox Code Playgroud)
附:
for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
DrugStrength aDrugStrength = it.next();
if (!aDrugStrength.isValidDrugDescription()) {
it.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
Edw*_*ale 25
与其他答案一样,您无法从正在迭代的集合中删除项目.您可以通过显式使用Iterator和删除项目来解决这个问题.
Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
Item blah = iter.next();
if(...) {
iter.remove(); // Removes the 'current' item
}
}
Run Code Online (Sandbox Code Playgroud)
小智 16
我喜欢循环的逆序,例如:
int size = list.size();
for (int i = size - 1; i >= 0; i--) {
if(remove){
list.remove(i);
}
}
Run Code Online (Sandbox Code Playgroud)
因为它不需要学习任何新的数据结构或类.
在迭代循环时,您尝试在remove()操作中更改List值.这将导致ConcurrentModificationException.
按照下面的代码,这将实现您想要的,但不会抛出任何异常
private String toString(List aDrugStrengthList) {
StringBuilder str = new StringBuilder();
List removalList = new ArrayList();
for (DrugStrength aDrugStrength : aDrugStrengthList) {
if (!aDrugStrength.isValidDrugDescription()) {
removalList.add(aDrugStrength);
}
}
aDrugStrengthList.removeAll(removalList);
str.append(aDrugStrengthList);
if (str.indexOf("]") != -1) {
str.insert(str.lastIndexOf("]"), "\n " );
}
return str.toString();
}
Run Code Online (Sandbox Code Playgroud)