Mit ‘asList’ getaggte Artikel

Ich weiß nicht, ob ihr schon wusstet…

Freitag, 11. Dezember 2009

aber ich bin neulich über eine Sache gestolpert, die mir so nicht bewusst war:

Was passiert wohl beim Ausführen des folgenden Java-Codes?

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(8, 9, 10);
 
list.remove(0);
list.add(2);
list.addAll(list2);

Na wisst ihr es? Man bekommt eine UnsupportedOperationException. Und zwar für jede der list manipulierenden Methoden. Seltsam oder vielleicht doch nicht? Ich für meinen Teil war überrascht. Und auch die Java-Doc für Arrays.asList half mir auf dem ersten Blick nicht sofort weiter:

    /**
     * Returns a fixed-size list backed by the specified array.  (Changes to
     * the returned list "write through" to the array.)  This method acts
     * as bridge between array-based and collection-based APIs, in
     * combination with {@link Collection#toArray}.  The returned list is
     * serializable and implements {@link RandomAccess}.
     *
     * This method also provides a convenient way to create a fixed-size
     * list initialized to contain several elements:
     * 
     *     List<String>; stooges = Arrays.asList("Larry", "Moe", "Curly");
     * 
     *
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    public static <T> List<T> asList(T... a) {...}

Doch beim genaueren Hinsehen bzw. Überlegen wird es klarer: fixed-size list, a list view of the specified array sowie der Methodenname asList sagen aus, dass es sich nur um eine Ansicht des Arrays bzw. der Eingaben handelt. Die Arrays-Klasse benutzt nämlich unter der Haube die eigene Implementierung java.utils.Arrays.ArrayList und diese implementiert weder add noch remove aus dem List-Interface. Hmm… Irgendwie schon blöd, denn es gibt weder Arrays.toList, noch bietet etwa die konkrete Implementierung ArrayList den komfortablen Var-Args Parameter im Konstruktor. Zudem hätte ich mir eine eindeutigere Dokumentation gewünscht, die ausdrücklich darauf hinweist, dass das Hinzufügen bzw. Entfernen nicht möglich ist.

Möchte man nun trotzdem nicht auf den syntaktischen Zucker verzichten, hilft ein kleiner – zugegebenermasen unperformanter – Workaround:

List<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));

Und, habt ihr es gewusst?


Christian Schätzlein