java.util a deux classes ArrayList

introduction

Bonjour. C'est Kecho. ** Utilisez-vous ArrayList? ** ** Bien sûr, je l'utilise aussi beaucoup. Il y avait une chose inattendue, alors je vais la présenter.

quiz

Une exception d'exécution se produit dans les sources suivantes. Où est-ce?

String[] array = { "banana", "apple", "melon" }; //Créer un tableau
List<String> list1 = Arrays.asList(array); //Créer une liste à partir d'un tableau

List<String> list2 = new ArrayList<>();
list1.stream().forEach(e -> list2.add(e)); //Créer une liste avec les mêmes éléments que list1

list1.add("lemon"); //Ajouter à la liste1
list2.add("lemon"); //Ajouter à la liste2

System.out.print(list1); //Sortir le résultat de list1
System.out.print(list2); //Sortir le résultat de list2

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ La bonne réponse est list1.add ("lemon") `` `! L'exception suivante se produira.

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.add(AbstractList.java:153)
	at java.base/java.util.AbstractList.add(AbstractList.java:111)
	at Main2.main(Main2.java:44)

À propos, list2.add ("lemon") `` est exécuté normalement.

Pourquoi ai-je une exception?

Tout d'abord, jetons un coup d'œil à chaque classe

System.out.println(list1.getClass()); // class java.util.Arrays$ArrayList
System.out.println(list2.getClass()); // class java.util.ArrayList

Les deux sont ArrayList. ** Mais list1 est un ArrayList de la classe interne de la classe Arrays **

En d'autres termes, il existe deux classes ArrayList. (Doya)

Que contient java.util.Arrays $ ArrayList?

Jetons un coup d'œil à l'intérieur des tableaux. C'est trop long à écrire, mais la déclaration de nom de classe ressemble à ceci.

・ ・ ・
private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
・ ・ ・

Il est défini dans la classe interne. Et la méthode add n'est pas implémentée dans ArrayList.

Alors regardez la classe parente AbstractList. (La classe qui a été sortie dans le message d'erreur)

・ ・ ・
public boolean add(E e) {
    add(size(), e);
    return true;
}
・ ・ ・
public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
・ ・ ・

C'est le coupable! !! Il est implémenté pour lever une exception UnsupportedOperationException lorsqu'il est appelé.

Pourquoi cette implémentation ...

AbstractList est littéralement une classe abstraite, c'est donc une classe prérequise. Par conséquent, il semble qu'il soit implémenté pour lever une exception lorsqu'il est appelé sans héritage.

Non, je pense qu'il existe un moyen de changer l'implémentation de la méthode asList lorsqu'elle devient une interface, mais ... Veuillez me dire la personne détaillée ...

Résumé

Il existe les deux ArrayLists suivantes dans java.util ①class java.util.Arrays$ArrayListclass java.util.ArrayList

Notez que ① générera une exception lorsque vous appelez la méthode add.

Recommended Posts

java.util a deux classes ArrayList
Ruby & a deux significations opposées, non?