0

I had the below piece of code which returns ConcurrentModificationException. I could see some approaches to handle the same in java7. Instead what is the best way to handle the same in Java 8

List<String> mylist = new ArrayList<>();
        mylist.add("test");

        mylist.forEach(str -> {
            if(str.equalsIgnoreCase("test"))
            {
                mylist.add("pass");
            }
        });
Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Prasad
  • 1,164
  • 1
  • 10
  • 27
  • 7
    I'd say the best approach to avoid it is to avoid manipulating the collection while you're iterating it. – daniu Mar 22 '19 at 09:40
  • 1
    Avoid concurrent modifications? So, seriously: the real approach is to **understand** what you are doing. In case of exceptions, it typically helps to enter their name /parts of the message into a search engine. It also helps to read the javadoc for such exceptions thrown by standard java. In other words: researching the problem is the best approach. – GhostCat Mar 22 '19 at 10:07

1 Answers1

0

I'd say the best approach to avoid it is to avoid manipulating the collection while you're iterating it.

You can do

if (myList.stream()
      .filter(s -> "test".equalsIgnoreCase(s))
      .findFirst()
      .isPresent()) {
    myList.add("pass");
}

or simpler, as Ole points out

if (myList.stream()
          .anyMatch("test"::equalsIgnoreCase)) {
    myList.add("pass");
}

EDIT: Ooops, Naman is right, you want to add as many "pass"s as matches, so

long matches = list.stream()
                   .filter("test"::equalsIgnoreCase)
                   .collect(Collectors.counting());
for (long i = 0; i < matches; i++) {
    list.add("pass");
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
daniu
  • 14,137
  • 4
  • 32
  • 53
  • 1
    Correct. Simpler: `if (myList.stream().anyMatch(s -> s.equalsIgnoreCase("test")))` or even `if (myList.stream().anyMatch("test"::equalsIgnoreCase))`. (`isPresent` is low-level and seldom needed; in 19 out of 20 there is a better solution without it.) – Ole V.V. Mar 22 '19 at 09:52
  • 1
    Why the downvote, please? This answer is correct and more to the point than the top answers of the linked original questions. – Ole V.V. Mar 22 '19 at 09:58
  • 1
    @OleV.V. The code differs from the one in question entirely. In this only one element found would result in a single added element while in the question, for every such conditional occurrence there is an addition. Apart from that, the question is more about how to avoid ConcurrentModificationException which the answer doesn't reflect upon. – Naman Mar 22 '19 at 10:00
  • True, @Naman (whether the list may contain `"test"` multiple times is not clear from the question). – Ole V.V. Mar 22 '19 at 10:03
  • 1
    @Naman You're right, edited the answer. – daniu Mar 22 '19 at 10:06
  • 2
    If you are really into brevity, you don’t need the loop in the last case: `myList.addAll(Collections.nCopies(Math.toIntExact(matches), "pass"));`. – Ole V.V. Mar 22 '19 at 10:11
  • 2
    …and instead of `.collect(Collectors.counting())` use just `.count()`. – Holger Mar 22 '19 at 12:43