Récemment, j'ai pris le temps d'analyser le code source de la méthode asList de la classe d'outils Java Arrays, j'ai compilé les informations pertinentes en ligne et je les ai enregistrées, j'espère que cela pourra également aider les lecteurs !
La classe d'outils Arrays fournit une méthode asList, qui peut être utilisée pour convertir un paramètre ou un tableau de longueur variable en liste.
Le code source est le suivant :
/** * 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}. * * <p>This method also provides a convenient way to create a fixed-size * list initialized to contain several elements: * <pre class="brush:php;toolbar:false"> * 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 */ @SafeVarargs public static
Découverte de problèmes
Selon la description de la méthode ci-dessus, écrivons d'abord quelques exemples :
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to","Java", "world"); System.out.println(array1); /**使用数组*/ List<String> array2 = Arrays.asList(new String[] {"Welcome", "to","Java", "world"}); System.out.println(array2); } }
Exécutez le programme ci-dessus et affichez le contenu suivant.
[Bienvenue, à, Java, monde]
[Bienvenue, à, Java, monde]
Sur un coup de tête, j'ai soudain envie d'ajouter une chaîne au créé liste" Cool~~~", Allez-y.
/**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to","Java", "world"); array1.add("Cool~~~");
En conséquence, une UnsupportedOperationException a été rencontrée :
Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(Unknown Source) at java.util.AbstractList.add(Unknown Source) at test.ArrayExample.main(ArrayExample.java:36)
Incroyablement, la liste générée par new ArrayList<>(a) a appelé l'ajout méthode, et il s’est avéré que j’ai rencontré un problème.
Recherche de cause
Alors la question est : que s'est-il passé ? En gardant des questions à l’esprit, voyons à quoi ressemble l’ArrayList utilisée dans Arrays.asList ?
Il s'avère que la classe ArrayList utilisée par la méthode asList de Arrays est une classe définie en interne, pas la classe java.util.ArrayList.
Le code source est le suivant :
/** * @serial include */ private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { if (array==null) throw new NullPointerException(); a = array; } public int size() { return a.length; } public Object[] toArray() { return a.clone(); } public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } public E get(int index) { return a[index]; } public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } public int indexOf(Object o) { if (o==null) { for (int i=0; i<a.length; i++) if (a[i]==null) return i; } else { for (int i=0; i<a.length; i++) if (o.equals(a[i])) return i; } return -1; } public boolean contains(Object o) { return indexOf(o) != -1; } }
Comme le montre l'implémentation de cette classe interne ArrayList, elle hérite du classe abstraite java. util.AbstractList
Cependant, par défaut, la classe java.util.AbstractList lancera directement UnsupportedOperationException dans les méthodes add, set et delete. Une partie du code source de AbstractList est la suivante :
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractList() { } public E set(int index, E element) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ public void add(int index, E element) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { throw new UnsupportedOperationException(); } }
C'est précisément parce que la classe interne ArrayList de la classe java.util.Arrays ne remplacez les méthodes add et delete, donc, lorsque nous appelons sa méthode add, nous appelons en fait la méthode add de la classe AbstractList, et le résultat est qu'une UnsupportedOperationException est levée directement.
De même, lorsque vous appelez la méthode Remove ou que vous appelez d'autres méthodes (telles que addAll) associées aux méthodes Add et Remove, vous rencontrerez également une exception UnsupportedOperationException.
Exemple AddAll :
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world"); array1.addAll(Arrays.asList("AAA", "BBB")); } }
Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(Unknown Source) at java.util.AbstractList.add(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at test.ArrayExample.main(ArrayExample.java:36)
exemple défini :
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world"); System.out.println(array1); //将Java替换成hello array1.set(2, "hello"); System.out.println(array1); } }
C'est précisément parce que la classe interne ArrayList of Arrays réécrit la méthode set, de sorte que le programme ci-dessus peut s'exécuter normalement et ne lancera plus UnsupportedOperationException.
Les résultats sont les suivants :
[Bienvenue, dans Java, monde]
[Bienvenue, dans, bonjour, monde]
Scénarios d'utilisation
À en juger par les exemples ci-dessus et par une analyse simple, la classe d'outils Arrays fournit une méthode asList, qui peut être utilisée pour convertir un paramètre ou un tableau de longueur variable en liste.
Cependant, la longueur de la Liste générée est fixe ; des opérations de modification peuvent être effectuées (par exemple, modifier un élément à une certaine position) ; ne peut pas être effectué. UnsupportedOperationException sera levée.
Arrays.asList est plus adapté aux scénarios dans lesquels vous disposez déjà de données de tableau ou de certains éléments et devez créer rapidement une liste, qui n'est utilisée que pour lire des opérations sans ajouter ni supprimer d'opérations.
Si vous souhaitez obtenir rapidement une liste qui peut être ajoutée, supprimée, modifiée et vérifiée en fonction des données connues du tableau, une méthode relativement simple est la suivante :
Réutilisez le java.util Couche wrapper .ArrayList.
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = new ArrayList<>(Arrays.asList("Welcome", "to", "Java", "world")); System.out.println(array1); array1.add("Cool~~~"); System.out.println(array1); } }
Les résultats sont les suivants :
[Bienvenue, à, Java, monde]
[Bienvenue, à, Java, world , Cool~~~]
Merci d'avoir lu, j'espère que cela pourra aider tout le monde, merci à tous d'avoir soutenu ce site !
Pour plus d'analyses du code source Java et une explication détaillée de la méthode Arrays.asList, veuillez faire attention au site Web PHP chinois !