遍历列表并添加到列表而不会引发 ConcurrentModificationException - Java
Iterate through list and add to list without incurring ConcurrentModificationException - Java
抱歉,这已经死了,但我真的很难实施这个问题的解决方案,而且我对 Java 还很陌生。
我需要能够调用基本上允许将 Person 对象添加到列表中的方法。
我在尝试实施解决方案时遇到的主要问题是 'ConcurrentModificationException' 这是可以理解的,因为我一直在 for each 循环的中间尝试更新列表。
因此,我提出了以下解决方案来防止 'ConcurrentModificationException' 但我的解决方案无法正常工作并且看起来过于复杂 - 请参阅以下方法代码片段:
public void addPerson(Person aPerson) {
// tempPersons list for temporarily storing Person objects
tempPersons = new ArrayList<>();
// if persons list is initially empty, add aPerson object to it
if (persons.isEmpty()) {
persons.add(aPerson);
}
// if persons list is not initially empty
if (!persons.isEmpty()) {
// loop through persons list
for (Person anotherPerson : persons) {
// if persons list anotherPerson first name is the same as the aPerson first name, print message
if (anotherPerson.getFirstName().equals(aPerson.getFirstName())) {
System.out.println("The Person " + aPerson.getFirstName() +
" is already entered in the list");
}
// otherwise add the aPerson object to the tempPersons list
else {
tempPersons.add(aPerson);
}
}
// once out of loop, add the tempPersons list to the persons list
persons.addAll(tempPersons);
// create new tempPersons2 list based on a hashset of the persons list so there are no duplicates
List<Person> tempPersons2 = new ArrayList<>(
new HashSet<>(persons));
// assign tempPersons2 list without duplicates to persons list
persons = tempPersons2;
}
}
因此,例如,如果我使用唯一和重复对象(aPerson 参数)的混合分别调用上述 addPerson 方法 4 次,该方法正确地识别出其中已经有一个具有相同名字的对象,但是人员列表似乎总是以重复的对象(名字)结尾,例如如果我有以下对象:
人1
名字 = 鲍勃
人2
名字 = 简
人 3
名字 = 鲍勃
人4
名字 = 安
然后我分别调用以下方法 4 次:
addPerson(Person1);
addPerson(Person2);
addPerson(Person3);
addPerson(Person4);
当我调用打印方法时,我得到以下输出:
Bob 已输入列表
一月
安
鲍勃
鲍勃
我希望得到以下结果:
Bob 已经存在
一月
安
鲍勃
为所有华夫饼道歉,这对你们大多数人来说可能是一个非常简单的解决方案,但我已经坚持了几天。
可以在这里找到类似的文章,但我仍在努力。
Adding elements to a collection during iteration
您可以使用 Set 而不是 list,这将满足您的需要并实现比较器或可比较接口以进行人员比较
无需过多更改代码:
public void addPerson(Person person) {
// The guard is more or less a premature optimization and should be removed.
if (persons.isEmpty()) {
persons.add(person);
return;
}
for (Person anotherPerson : persons) {
if (anotherPerson.getFirstName().equals(person.getFirstName())) {
System.out.println("The Person " + person.getFirstName() +
" is already entered in the list");
return;
}
}
persons.add(person);
}
这将在找到匹配项时退出该方法,如果没有匹配项,则只需在循环后添加 person
。注意第一次检查中的return
。
此代码的优化可以使用 Map
或 Set
来加速包含检查;在 persons
上使用 anyMatch 也会导致更优雅的解决方案。
The duplicates are caused by your for
loop and it's else
condition. If Bob
and Jan
is in your collection and you add a second Bob
then Jan
won't be equal to Bob
and your else
path is executed adding a duplicate to your final persons
List
.
抱歉,这已经死了,但我真的很难实施这个问题的解决方案,而且我对 Java 还很陌生。
我需要能够调用基本上允许将 Person 对象添加到列表中的方法。
我在尝试实施解决方案时遇到的主要问题是 'ConcurrentModificationException' 这是可以理解的,因为我一直在 for each 循环的中间尝试更新列表。
因此,我提出了以下解决方案来防止 'ConcurrentModificationException' 但我的解决方案无法正常工作并且看起来过于复杂 - 请参阅以下方法代码片段:
public void addPerson(Person aPerson) {
// tempPersons list for temporarily storing Person objects
tempPersons = new ArrayList<>();
// if persons list is initially empty, add aPerson object to it
if (persons.isEmpty()) {
persons.add(aPerson);
}
// if persons list is not initially empty
if (!persons.isEmpty()) {
// loop through persons list
for (Person anotherPerson : persons) {
// if persons list anotherPerson first name is the same as the aPerson first name, print message
if (anotherPerson.getFirstName().equals(aPerson.getFirstName())) {
System.out.println("The Person " + aPerson.getFirstName() +
" is already entered in the list");
}
// otherwise add the aPerson object to the tempPersons list
else {
tempPersons.add(aPerson);
}
}
// once out of loop, add the tempPersons list to the persons list
persons.addAll(tempPersons);
// create new tempPersons2 list based on a hashset of the persons list so there are no duplicates
List<Person> tempPersons2 = new ArrayList<>(
new HashSet<>(persons));
// assign tempPersons2 list without duplicates to persons list
persons = tempPersons2;
}
}
因此,例如,如果我使用唯一和重复对象(aPerson 参数)的混合分别调用上述 addPerson 方法 4 次,该方法正确地识别出其中已经有一个具有相同名字的对象,但是人员列表似乎总是以重复的对象(名字)结尾,例如如果我有以下对象:
人1 名字 = 鲍勃
人2 名字 = 简
人 3 名字 = 鲍勃
人4 名字 = 安
然后我分别调用以下方法 4 次:
addPerson(Person1);
addPerson(Person2);
addPerson(Person3);
addPerson(Person4);
当我调用打印方法时,我得到以下输出:
Bob 已输入列表
一月
安
鲍勃
鲍勃
我希望得到以下结果:
Bob 已经存在
一月
安
鲍勃
为所有华夫饼道歉,这对你们大多数人来说可能是一个非常简单的解决方案,但我已经坚持了几天。
可以在这里找到类似的文章,但我仍在努力。
Adding elements to a collection during iteration
您可以使用 Set 而不是 list,这将满足您的需要并实现比较器或可比较接口以进行人员比较
无需过多更改代码:
public void addPerson(Person person) {
// The guard is more or less a premature optimization and should be removed.
if (persons.isEmpty()) {
persons.add(person);
return;
}
for (Person anotherPerson : persons) {
if (anotherPerson.getFirstName().equals(person.getFirstName())) {
System.out.println("The Person " + person.getFirstName() +
" is already entered in the list");
return;
}
}
persons.add(person);
}
这将在找到匹配项时退出该方法,如果没有匹配项,则只需在循环后添加 person
。注意第一次检查中的return
。
此代码的优化可以使用 Map
或 Set
来加速包含检查;在 persons
上使用 anyMatch 也会导致更优雅的解决方案。
The duplicates are caused by your
for
loop and it'selse
condition. IfBob
andJan
is in your collection and you add a secondBob
thenJan
won't be equal toBob
and yourelse
path is executed adding a duplicate to your finalpersons
List
.