Le déclencheur était J'ai lu la source de ArrayList. J'ai écrit ce qui m'intéressait j'ai lu la source de ArrayList, mais je voulais en savoir plus est.
"Je ne comprends pas la différence entre LL.116-126 EMPTY_ELEMENT DATA et DEFAULTCAPACITY_EMPTY_ELEMENTDATA. Comprenez-vous si vous continuez à lire? Cependant, ce dernier javadoc dit correctement: "C'est la différence." Ces commentaires sont importants. Mais je ne le comprends toujours pas. 』\
C'est vrai. Je sais ce que je veux faire, mais je ne comprends pas l'intention de le diviser en deux variables. Eh bien, j'étais curieux et j'ai vérifié.
Ensuite, la correction de première étape a été trouvée. Tout d'abord, retardez l'évaluation du constructeur par défaut. Certes, si c'est la source de l'ancien JDK, quand je regarde le constructeur, j'ai l'impression d'avoir tout de suite compris quelle taille doit être sécurisée par la valeur initiale. C'est un tableau vide. C'est celui qui l'a corrigé. 8011200: (coll) Optimize empty HashMap and ArrayList
public ArrayList() {
// this(10);
super();
this.elementData = EMPTY_ELEMENTDATA;
}
Au lieu d'allouer 10 séquences au début, rendez-le vide et développez-le une fois ajouté. C'est bon.
Ensuite, un correctif de deuxième étape a été trouvé. Ici, DEFAULTCAPACITY_EMPTY_ELEMENTDATA est ajouté. 8035584: ArrayList(c) should avoid inflation if c is empty
Lorsqu'une liste vide est passée avec public ArrayList (Collection <? Extend E> c) {, c.toArray (); est appelée et le nombre d'instances augmente régulièrement. Par conséquent, lorsque size == 0, j'ai défini this.elementData = EMPTY_ELEMENTDATA;. Je comprends que.
Alors pourquoi avez-vous changé this.elementData = EMPTY_ELEMENTDATA; en this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; quand public ArrayList () {? Eh bien, je ne sais pas.
À en juger par les deux modifications, lorsque le nouveau ArrayList () a été fait, il s'agissait à l'origine du nouveau ArrayList (10). Mais maintenant, je remplace un tableau vide. D'autre part, lorsque new ArrayList (0) est exécuté, un tableau vide est affecté. La même chose est vraie lors du passage d'une liste vide au constructeur.
En d'autres termes, lors de l'ajout pour la première fois après la création d'une instance, DEFAULTCAPACITY_EMPTY_ELEMENTDATA et EMPTY_ELEMENTDATA sont attribués séparément pour distinguer s'il a été créé avec le nouveau ArrayList () ou le nouveau ArrayList (0). ..
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
La différence entre 0 et 10 (DEFAULT_CAPACITY) est que lorsque ensureCapacity (5) est appelé, la taille de la mémoire tampon est à l'origine de 10 pour le nouveau ArrayList (), il est donc ignoré, et pour le nouveau ArrayList (0), la taille du tampon est de 0. La décision a été d'augmenter la taille du tampon à 5.
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
Lorsque ce maximum est également new ArrayList (), même si vous essayez d'ajouter à buffer size = 0 et de définir buffer size = 1, cela signifie que vous définissez soudainement buffer size = 10 (DEFAULT_CAPACITY).
Ne corrigez pas un autre problème avec le correctif "ArrayList (c) devrait éviter l'inflation si c est vide". Peut-être que c'est écrit quelque part.
Recommended Posts