【问题标题】:check if array contains values, if not then add to arraylist - Concurrent Modification Exception - Java检查数组是否包含值,如果不包含则添加到 arraylist - 并发修改异常 - Java
【发布时间】:2026-01-17 07:45:01
【问题描述】:

我将 String name 传递给一个方法,如果该 name 不在数组中,那么它会被添加。

我先尝试了这个,但得到了并发修改异常

List<String> people = new ArrayList<>();

public void addName(String name) {
    if (people.isEmpty()) {
        people.add(name);
    } else {
        for (String s : people) {
            if (s.equals(name)) {
                System.out.println("dont add");
            } else {
                people.add(name);
            }
        }
    }
}

在论坛上阅读后,我了解到您必须使用迭代器来避免这种情况。我尝试了它并修复了Concurrent Modification Exception,但是即使我声明如果它们存在于数组中就不会添加播放器,但当我传递列表中已经存在的名称时,我确实得到了这个输出“名称存在” ,但随后它也运行“添加名称”,所以不明白为什么会发生这种情况

if (people.isEmpty()) {
    people.add(name);
} else {
    String name2 = null;
    for (Iterator<String> it = people.iterator(); it.hasNext(); ) {
        String element = it.next();
        if (element.equals(name)) {
            String message = "name exists";
            System.out.println(message);
            name2 = null;
        } else if (!element.equals(name)) {
            System.out.println("Name added");
            name2 = name;
        }
    }
    if (name2 != null) {
        people.add(name2);
    }
}

【问题讨论】:

  • 嗯,你不能用people.contains(name);吗?
  • 这意味着如果一个名字是“don”那么你有另一个名字作为“驴”他们将匹配,如果数组中存在相同的名字,我只想不添加这个名字
  • “在阅读论坛后,我了解到您必须使用迭代器来避免这种情况。”那些论坛错了。 for-each 循环在功能上与使用 Iterator 相同,在这两种情况下,您都不能在迭代 Collection 时对其进行修改。按照 blahfunk 的建议使用 contains 方法。您的整个 addName 方法只需两行代码即可实现。 (关于您的评论:Collection.contains 与 String.contains 没有任何关系。Collection.contains 使用相等性,而不是子字符串测试。)
  • @CookieMonster 这不是真的。如果您正在检查单个字符串是否包含另一个字符串,则为 true,但您正在检查 ArrayList 是否包含它,而不是单个字符串。
  • @blahfunk 谢谢,我一开始对包含有点困惑,但效果很好

标签: java arrays iterator


【解决方案1】:

你可以这样做:

public void addName(String name) {
    if (!people.contains(name)) {
        people.add(name);
    }
}

【讨论】:

    【解决方案2】:

    听起来你正在尝试重新发明一个系列。

    Set<String> names = new TreeSet<>(); // Or set of your choice
    names.add("Joe"); // Set contents ["Joe"]
    names.add("Bob"); // Set contents ["Joe", "Bob"];
    names.add("Joe"); // Set contents ["Joe", "Bob"];
    

    如果你想要打印线

    if (names.add(name) {
      System.out.println("Added name " + name);
    } else {
      System.out.println("Already added " + name);
    }
    

    【讨论】:

      【解决方案3】:

      我认为,一旦您发现该名称已经存在,您就需要跳出循环。否则name2 可能会设置为null,然后再次设置为非空值。

      例如:

                 for (Iterator<String> it = people.iterator(); it.hasNext(); ) {
                      String element = it.next();
                      if (element.equals(name)) {
                          String message = "name exists";
                          System.out.println(message);
                          name2 = null;
                          break;
                      } else if(element.equals(name)==false) {
                          System.out.println("Name added");
                          name2 = name;
                      }
                  }
      

      但请查看contains,因为这是一种更简洁的方法!

      【讨论】: