Dlaczego tak
Pętla for-each korzysta z iteratora listy. Po usunięciu elementu 2 metodą listy, a nie iteratora, licznik modyfikacji listy różni się od zapamiętanego w iteratorze, więc najbliższe wywołanie next() zgłasza ConcurrentModificationException. Poprawnie usuwa się elementy przez it.remove() albo l.removeIf(x -> x % 2 == 0). Wynik [1, 3] dałby właśnie taki poprawiony kod, a kod się kompiluje, więc błąd ujawnia się dopiero w czasie wykonania.