Java 8: UnsupportedOperationException

mrbela

Bekanntes Mitglied
Hey Leute!

Ich probiere mich gerade in Java 8 aus und bin prompt auf eine Frage gestoßen:

Java:
    public static void main(String[] args) {

        Predicate<String> isNotIch = str -> !str.equalsIgnoreCase("Ich");

        // damit gehts!
        // List<String> names = new ArrayList<>();
        // names.addAll(Arrays.asList("Ich", "Du", "Er/Sie/Es", "Wir", "Ihr",
        // "Sie"));

        // Hier gibt es eine UnsupportedOperationException
        List<String> names = Arrays.asList("Ich", "Du", "Er/Sie/Es", "Wir", "Ihr", "Sie");

        names.forEach(str -> System.out.println("--- DAVOR ---> " + str));
        names.removeIf(isNotIch);

        names.forEach(str -> System.out.println("--- DANACH ----> " + str));
    }

Die Ausgabe hiervon ist:

Java:
--- DAVOR ---> Ich
--- DAVOR ---> Du
--- DAVOR ---> Er/Sie/Es
--- DAVOR ---> Wir
--- DAVOR ---> Ihr
--- DAVOR ---> Sie
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161)
    at java.util.AbstractList$Itr.remove(AbstractList.java:374)
    at java.util.Collection.removeIf(Collection.java:415)
    at ZweitesBeispiel.main(ZweitesBeispiel.java:19)

Benutze ich wie im ersten Fall eine ArrayList, dann läuft das Programm einfach durch. Ausgabe:

Java:
--- DAVOR ---> Ich
--- DAVOR ---> Du
--- DAVOR ---> Er/Sie/Es
--- DAVOR ---> Wir
--- DAVOR ---> Ihr
--- DAVOR ---> Sie
--- DANACH ----> Ich

Beim zweiten Beispiel nicht!

Woran liegt das genau? Man sollte ja meinen, dass beide (!) Varianten, da sie ja vom Typ List<String> sind, fehlerfrei durchlaufen sollten! Das sieht für mich auch einem "schlechten Design" aus, finde ich.

Ich danke Euch für die Hilfe.
 
asList gibt eine ArrayList mit einem Array in einer fixed Grösse zurück und ist quasi nur ein "Wrapper" um das Array. Add, remove usw... sind nicht möglich. set funktioniert, da es nur die Werte ändert.
 
Findest Du nicht, dass das ein schlechtes Design ist? Bei der einen List funktioniert es, bei der anderen nicht?! Das ist ja nicht wirklich elegant, oder?
 
Mag ich nicht wirklich beurteilen... Auf jeden Fall ist es halt eine innerClass von Arrays und überschreibt die remove Methoden nicht, welche dann die entsprechende Exception throwen.

Java:
List<String> names = new LinkedList<String>(Arrays.asList("Ich", "Du", "Er/Sie/Es", "Wir", "Ihr", "Sie"));

Was beim löschen auch den Vorteil hat performanter zu sein.
 
Für mich ein klarer Design Fehler. Wenn eine List per Definition mutable ist, dann muss sie es auch immer sein. In diesem Fall müßte man halt einen neuen Typ FixedList oder sowas einführen

Gruß

Claus
 

Neue Themen


Zurück
Oben