遍历列表并添加到列表中,而不会引发ConcurrentModificationException-Java



很抱歉,这已经做得很糟糕了,但我真的很难实现这个问题的解决方案,而且我对Java还很陌生。

我需要能够调用一个方法,该方法基本上允许将Person对象添加到列表中。

我在尝试实现解决方案时遇到的主要问题是"并发修改异常",这是可以理解的,因为我一直在尝试更新列表,同时处于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-param(分别调用上述addPerson方法4次,该方法会正确地识别出已经有一个同名对象,但人员列表似乎总是以重复对象(名字(结尾,例如,我有以下对象:

人物1FirstName=Bob

人物2FirstName=Jan

人物3FirsName=Bob

人物4FirstName=Ann

然后我进行以下方法调用4次:

addPerson(Person1(;

addPerson(Person2(;

addPerson(Person3(;

addPerson(Person4(;

当我调用打印方法时,我得到以下输出:

Bob已经输入到列表中

1月

Bob

Bob

我期望以下内容:

Bob已经出现

1月

Bob

为所有的华夫饼道歉,对你们大多数人来说,这可能是一个非常简单的解决方案,但我已经坚持了几天了。

类似的文章可以在这里找到,但我仍在挣扎。

在迭代期间向集合添加元素

在不太多更改代码的情况下:

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

该代码的优化可以使用MapSet来加快包含检查;此外,仅在persons上使用anyMatch将带来更优雅的解决方案。

重复是由for循环和else条件引起的。如果BobJan在您的集合中,并且您添加了第二个Bob,则Jan将不等于Bob,并且执行else路径,将副本添加到最终的personsList

您可以使用Set而不是list,这将满足您的需求,并实现用于人员比较的比较器或可比较接口

相关内容

  • 没有找到相关文章

最新更新