ArrayListEst la collection la plus utilisée dans notre développement,Mais beaucoup de gens ne connaissent pas son code source,Au moment de l'entrevue,Questions un peu plus approfondies posées par l'intervieweur,Je ne peux pas répondre,Aujourd'hui, nous allons explorerArrayListCode source.

1. Introduction

  • ArrayListAu rez - de - chaussée se trouve le tableau,L'élément admissible estnull,Capacité d'expansion dynamique
  • size、isEmpty、get、set、add La complexité temporelle de la méthode d'attente est O (1)
  • Sécurité non threadée,Modification simultanée,Va lancerConcurrentModificationException

2. Initialisation

// Capacité initiale
private static final int DEFAULT_CAPACITY = 10; // Tableau vide
private static final Object[] EMPTY_ELEMENTDATA = {}; // Tableau vide par défaut
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // Tableau des éléments de stockage
transient Object[] elementData; // Initialisation sans paramètres,Par défaut est un tableau vide
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
} // Initialisation avec paramètres, Spécifiez la taille de la capacité
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
}
}

N'oubliez pas: Lors de l'initialisation sans paramètres ,Par défaut est un tableau vide, Taille de la capacité non initialisée , La capacité n'est initialisée que lorsque l'élément est ajouté pour la première fois .

3. Ajouter un élément

public boolean add(E e) {
// Assurez - vous que la capacité du tableau est suffisante ,sizeEst le nombre d'éléments
ensureCapacityInternal(size + 1);
// Affectation directe
elementData[size++] = e;
return true;
} // Assurez - vous que la capacité du tableau est suffisante
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
} // Calcul de la capacité minimale requise
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// Si le tableau est égal à un tableau vide ,La capacité minimale est de10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
} private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// Si la capacité minimale requise est supérieure à la longueur du tableau ,Pour augmenter la capacité
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

Regardez la logique d'expansion :

// Expansion de la capacité, C'est copier de vieilles données dans un nouveau tableau 
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// oldCapacity >> 1 Oui.oldCapacityDivisé par2,Ça veut dire...1.5Double expansion
int newCapacity = oldCapacity + (oldCapacity >> 1); // Si la capacité agrandie est inférieure à la capacité minimale , La capacité agrandie est égale à la capacité minimale
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // Si la capacité agrandie est supérieure àIntegerValeur maximale de,C'est bon.IntegerMax.
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity); // Échelle et assigne une valeur au tableau original
elementData = Arrays.copyOf(elementData, newCapacity);
}

Je vois.:

  • L'expansion de la capacité est basée sur la capacité initiale 1.5Double expansion, Ce n'est pas un doublement de la capacité
  • La capacité maximale estIntegerValeur maximale de
  • Lors de l'ajout d'un élément, Aucun élément n'a été vérifié ,C'est possible.null

Regardez encore la logique de la copie de tableau ,Tout estArrays Les méthodes de la classe :

/**
* @param original Tableau original
* @param newLength Nouvelle taille de capacité
*/
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
} public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
// Créer un nouveau tableau, La capacité est la nouvelle taille de capacité
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
// Copier les éléments du tableau original dans le nouveau tableau
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}

Enfin appeléSystem Méthode de copie de tableau pour la classe ,- Oui.nativeMéthodes:

/**
* @param src Tableau original
* @param srcPos Position de départ du tableau original
* @param dest Tableau cible
* @param destPos Position de départ du tableau cible
* @param length Longueur copiée
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);

4. Supprimer un seul élément

public boolean remove(Object o) {
// Déterminer si l'élément à supprimer est null
if (o == null) {
// Traverser le tableau
for (int index = 0; index < size; index++)
// Si l'élément est égal à l'emplacement actuel , Supprimer l'élément à l'emplacement actuel
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
// Traverser le tableau
for (int index = 0; index < size; index++)
// Si l'élément est égal à l'emplacement actuel , Supprimer l'élément à l'emplacement actuel
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
} // Supprimer l'élément à cet endroit
private void fastRemove(int index) {
modCount++;
// Calculer le nombre d'éléments à déplacer
int numMoved = size - index - 1;
if (numMoved > 0)
// Deindex+1Position pour commencer la copie, C'est - à - dire que l'ensemble des éléments suivants se déplace d'une position à gauche
System.arraycopy(elementData, index+1, elementData, index, numMoved);
// Le dernier élément du tableau est assigné à null, Prévenir les fuites de mémoire
elementData[--size] = null;
}

Je sais.,Supprimer l'élément,C'est traverser le tableau, Si la comparaison circulaire est égale à la valeur cible .Si égal, Déplacez l'élément entier derrière cette position d'une position à gauche , Et assigner le dernier élément du tableau à null.

5. Suppression par lots

// Suppression par lotsArrayListEt collectionscDes éléments qui existent tous
public boolean removeAll(Collection<?> c) {
// Vérification non nulle
Objects.requireNonNull(c);
// Suppression par lots
return batchRemove(c, false);
} private boolean batchRemove(Collection<?> c, boolean complement){
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
// Déplacer les éléments à gauche
elementData[w++] = elementData[r];
} finally {
// En cas d'anomalie,Peut - être pas égal
if (r != size) {
// 1: Ça pourrait être au - dessus for Une anomalie s'est produite dans la boucle
// 2: Peut - être que d'autres fils ont ajouté des éléments
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
// Assigner un élément qui n'a pas besoin d'être conservé comme null
if (w != size) {
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}

Je sais., Lors de la suppression par lots , Une seule copie du tableau est effectuée ,Comparerfor Boucler une seule suppression plus efficace , Donc quand vous supprimez un lot d'éléments ,Utilise - le autant que possible.removeAll()Méthodes.

5. Résumé

Cet article analyseArrayListInitialisation de、put、add、remove、 Source sous - jacente de méthodes telles que l'expansion dynamique ,Je crois que tout le monde est d'accord avecArrayListAvec une meilleure compréhension, La prochaine leçon LinkedListSource de.

Quelqu'un a dit:ArrayList- Oui.2Double expansion, Aujourd'hui, je vais te déchirer la main ArrayListAutre article Afghanistan

  1. Planez votre série ——Déchirure des mainsArrayList

    Pas grand - choseBB,Directement au Code: public class MyArrayList { //Créer un objet Array private Object[] elements; // Longueur du tableau utilisée private int siz ...

  2. Java - ArrayListAnalyse des sources

    javaArticle amélioré(Deux.)-----ArrayList Un..ArrayListGénéralités ArrayListEst la réalisationListUn tableau dynamique des interfaces,Ce qu'on appelle la dynamique, c'est que sa taille est variable.Toutes les opérations de liste optionnelles sont réalisées,Et permet d'inclure nul ...

  3. Java Analyse du code source sous - jacent générique -ArrayList,LinkedList,HashSetEtHashMap

    Déclaration: Le code source suivant est basé sur JDK1.8_112Version 1. ArrayListAnalyse du code source <1. La collection contient toujours une référence à l'objet, pas à l'objet lui - même , Et le type de données natives ne peut pas être placé , Nous avons besoin de paquets avec des types de données natifs ...

  4. Java Petite Collection blanche de sources d'apprentissage :ArrayList

    ArrayListApprentissage des sources Cet article est basé surJDK1.8Version, Aux géants de la collection ArrayList Faire un certain apprentissage du code source , Il y aura beaucoup de références , Un lien vers l'article de référence sera donné après l'article , Cet article est utilisé pour consolider les connaissances d'apprentissage . ArrayListDe ...

  5. Java8Cadre de collecte——ArrayListAnalyse des sources

    java.util.ArrayList Les principaux points sont les suivants: ,De Java 8 On y va.: Un..ArrayList Aperçu des caractéristiques de 2..ArrayListMise en œuvre interne de: En commençant par les propriétés internes et les constructeurs Trois.ArrayLis ...

  6. EnsembleArrayList(Y comprisJDK1.8Analyse des sources)

    Un..ArrayListStructure des données pour ArrayListLa structure de données sous - jacente est un tableau,Le type d'élément Array estObjectType,C'est - à - dire que tous les types de données peuvent être stockés.Nous sommes d'accord avecArrayList Toutes les actions d'une instance d'une classe (Ajouter, supprimer, modifier et vérifier), Au rez - de - chaussée. ...

  7. JAVAQuestions d'entrevue ManuscritArrayListRéalisation,Passer l'examen écrit?

    L'intervieweurQ1:Peut écrire unArrayList Une simple mise en œuvre de ? Nous le savons tous.ArrayListEst basé sur une implémentation de tableau,Si vous le faitesJDKCode sourceArrayListMoyenneadd().remove().get()Méthodes, Tu sais comment ...

  8. (Un.)ArrayListAnalyse des sources de collecte

    Un..ArrayListCaractéristiques de l'ensemble Questions Noeud      Sur ArrayListAutoriser null Allow ArrayListAutoriser la duplication des données Allow ArrayListOrdre Ordre. ArrayListSi le fil est sécurisé ...

  9. Analyse du code source II(ArrayListAvecLinkedListLa différence entre)

    Un.:Regardez d'abord.ArrayList Architecture de classe : public class ArrayList<E> extends AbstractList<E> implements Lis ...

  10. JDK12En basArrayListInterprétation du code source Avec VectorComparaison

    ArrayListLecture du code source. // Le Code d'essai est implémenté comme suit: private static void arrayList() { ArrayList<String> list = new Array ...

Recommandation aléatoire

  1. InjavaUtilisé dans le projetAES256 CBCCryptage

    Il faut d'abord faire attention,Par défautJDKN'est pas pris en charge256Bitencrypted,J'en ai besoin.Oracle Téléchargement du fichier d'amélioration du chiffrement sur le site officiel (Java Cryptography Extension (JCE) Unlimited Strength J ...

  2. HDU 4831 Scenic Popularity (Arbre de segment)

    Scenic Popularity Problem Description Près du festival , Les ours ont récemment l'intention de visiter le parc en plein air . À l'intérieur du parc, il y a beaucoup d'attractions touristiques et de zones de repos , Parce que les attractions touristiques sont très populaires , Entraînant des attractions et des zones de repos ...

  3. Dans la structure des données, Représentation structurelle de plusieurs types d'arbres (CMise en œuvre linguistique)

    //***************************************** // Plusieurs définitions de la structure de l'arbre //***************************************** # ...

  4. Créer et enregistrer des personnalisations HTTP Module

    Cette visite démontre la personnalisation HTTP Fonctions de base du module. Pour chaque demande,Doit être appelé HTTP Module de réponse BeginRequest Et EndRequest Événements. Donc,,Le module fonctionne avant et après le traitement de la demande. Si ...

  5. HBaseSnapshot

    CDH- Oui.Cloudera Entièrement open source distribué pour Apache Hadoop Et les projets connexes (Y compris:Apache HBase).CDHVersion actuelle de(4.2)Une introductionHBase De nouvelles fonctionnalités ont récemment été ajoutées au tronc , Permet à l'utilisateur d'entrer dans le tableau spécifié ...

  6. phpSupprimer un fichier ou un dossier

    <?php function deleteDir($dir) { if (!$handle = @opendir($dir)) { return false; } while (false != ...

  7. Java Couper l'image

    package com.test; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.Ima ...

  8. Reducing and Profiling GPU Memory Usage in Keras with TensorFlow Backend

    keras Allocation adaptative de la mémoire vive & Purger la libération des variables inutilisées GPU Mémoire apparente Intro Are you running out of GPU memory when using keras or ten ...

  9. transfer function

    Après un changement linéaire , On s'attend souvent à des changements non linéaires , Les fonctions de changement non linéaires couramment utilisées sont les suivantes: Sigmoid,Tanh,ReLU.On verra., Après avoir changé ces trois fonctions, ,Tensor Les dimensions ne changent pas . tanh(Fonction tangente hyperbolique):

  10. What’s a service mesh? And why do I need one?

    https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/ Update 2018-02-06: Since t ...