[JAVA] Résoudre le problème de l'accès aléatoire lent pour linkedList, une classe de type collection

Après avoir lu l'article Mécanismes et caractéristiques des classes d'implémentation de collection souvent utilisées en Java, utilisez arrayList pour implémenter le mécanisme que vous essayez de créer. Je me demandais lequel de la LinkedList est le meilleur, donc j'écrirai le résultat de la vérification du temps de calcul.

Le mécanisme que j'ai essayé de faire

Ce que j'ai essayé de faire était un "tableau de routes". Pour la fonction f définie pour les nombres naturels supérieurs ou égaux à 2 Nous définissons n 2 </ sub> comme n 2 </ sub> = f (n 1 </ sub>) en utilisant le nombre naturel n 1 </ sub>. Ceci est répété jusqu'à ce que n m </ sub> soit hors de la plage de définition de f. À ce moment-là, je veux enregistrer n k (1 <= k <= m) </ sub> en tant que tableau.

Après avoir sécurisé le tableau, recherchez les éléments dans le chemin et extrayez la plus petite valeur de la plage qui remplit les conditions (par exemple, la plage qui ne peut être déterminée que si le tableau entier est déterminé, comme les 10 nombres au milieu du tableau). Je vise.

Pourquoi vous devriez utiliser le type de collection

La raison pour laquelle vous devriez utiliser le type de collection au lieu d'un tableau normal est que *** la longueur du tableau est indéterminée ***. Compte tenu de ce point, je pense que la liste chaînée est meilleure car il est facile d'ajouter des séquences. D'autre part, on craint que la vitesse de calcul puisse être lente s'il s'agit d'une liste liée car l'accès aux éléments du tableau est nécessaire pour détecter la valeur minimale.

Directives comportementales

Sur la base de ce qui précède, considérez la classe à utiliser.

-Vérifiez la vitesse de recherche des éléments de linkedList après avoir créé un tableau. -Si la vitesse de calcul est lente, comparez-la à la vitesse d'ajout de tableau de l'arraylist. -Si la vitesse de calcul peut être tolérée, implémentez-la en utilisant la liste chaînée telle quelle.

Commencer le calcul réel

La raison pour laquelle la recherche d'élément de la linkedList est lente est que la liste liée n'a pas l'index de l'élément entier, mais uniquement les informations des éléments avant et après celui-ci. C'est parce que nous devons suivre. Par conséquent, l'accès aléatoire est plus lent que l'arraylist, qui a un index pour l'élément entier. Cependant, ce que j'essaye de faire cette fois, c'est d'extraire un certain nombre d'éléments d'un certain élément et de trouver la valeur minimale parmi eux. Dans ce cas, si la valeur d'un élément peut être obtenue et les informations pour l'élément suivant peuvent être obtenues en même temps, n'y a-t-il pas de perte de vitesse?

Par conséquent, le code suivant est utilisé pour la comparaison à l'aide de l'instruction for et de l'instruction for étendue.

test.java


import java.util.LinkedList;
import java.util.Iterator;

public class test {
    static final int LIMIT = 100_000;
    static LinkedList<Integer> array =  new LinkedList<Integer>();
    static long sum = 0;

    static {
        for (int i = 0; i < LIMIT; i++) {
            array.addLast(i);
        }
    }

    static void addArrayNumbersWithFor() {
        sum = 0L;
        for (int i = 0; i < LIMIT; i++) {
           sum += array.get(i);
        }
        
    }

    static void addArrayNumbersWithAppliedFor() {
        sum = 0L;
        for (int value : array) {
           sum += value;
        }
        
    }

    static double measureCalculationTimeWithFor() {
        //Obtenez l'heure de début en millisecondes
        long ts1 = System.currentTimeMillis();
        //Exécution du traitement
        addArrayNumbersWithFor();
        //Obtenez l'heure de fin en millisecondes
        long te1 = System.currentTimeMillis();
        //Temps de traitement milliseconde
        long tmsec1 = te1 - ts1;
        //Temps de traitement secondes
        double tsec1 = (double) tmsec1 / 1000.0;

        System.out.println(sum);

        return tsec1;
    }

    static double measureCalculationTimeWithAppliedFor() {
        //Obtenez l'heure de début en millisecondes
        long ts1 = System.currentTimeMillis();
        //Exécution du traitement
        addArrayNumbersWithAppliedFor();
        //Obtenez l'heure de fin en millisecondes
        long te1 = System.currentTimeMillis();
        //Temps de traitement milliseconde
        long tmsec1 = te1 - ts1;
        //Temps de traitement secondes
        double tsec1 = (double) tmsec1 / 1000.0;

        System.out.println(sum);

        return tsec1;
    }

    public static void main(String[] args) {
        System.out.println(test.measureCalculationTimeWithAppliedFor());
        System.out.println(test.measureCalculationTimeWithFor());
  }
}
Le résultat est, pour la phrase: 4,943 secondes Étendu pour l'instruction: 0,008 seconde

A partir de ce résultat, lorsqu'une instruction for simple est utilisée, les éléments sont toujours acquis dans l'ordre à partir du premier élément de la boucle, alors que dans le cas de l'instruction for étendue, les informations de l'élément suivant sont obtenues à partir de l'élément précédent. On peut voir qu'il est acquis et l'élément suivant est acquis.

Résumé

Si vous souhaitez ajouter des éléments à un tableau les uns après les autres et que vous ne savez pas combien en ajouter, vous voudrez utiliser une liste liée. Le goulot d'étranglement est la vitesse lente de l'accès aléatoire, mais on peut voir qu'il n'y a pas de vitesse lente car les éléments sont acquis dans l'ordre depuis le début en utilisant l'instruction for étendue. Je ne l'ai pas comparé à un tableau normal, mais il est basé sur l'hypothèse que le type de collection sera utilisé.