Maison > Java > javaDidacticiel > Analyse du code source Java Explication détaillée de la méthode Arrays.asList

Analyse du code source Java Explication détaillée de la méthode Arrays.asList

高洛峰
Libérer: 2017-02-04 10:11:52
original
1500 Les gens l'ont consulté

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 List asList(T... a) { return new ArrayList<>(a); }
Copier après la connexion

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);
 }
 
}
Copier après la connexion

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~~~");
Copier après la connexion

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)
Copier après la connexion

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;
   }
 }
Copier après la connexion

Comme le montre l'implémentation de cette classe interne ArrayList, elle hérite du classe abstraite java. util.AbstractList, mais les méthodes d'ajout et de suppression ne sont pas remplacées et aucune implémentation spécifique n'est donnée.

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();
  }
}
Copier après la connexion

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"));
  }
 
}
Copier après la connexion

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)
Copier après la connexion

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);
  }
 
}
Copier après la connexion

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);
 
  }
 
}
Copier après la connexion

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 !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal