web-dev-qa-db-fra.com

Effectuer la recherche la plus rapide - quelle collection dois-je utiliser?

Je connais:

  • Si vous avez besoin d'un accès rapide aux éléments à l'aide de l'index, ArrayList devrait être le choix.
  • Si vous avez besoin d'un accès rapide aux éléments à l'aide d'une clé, utilisez HashMap.
  • Si vous avez besoin d'ajouter et de supprimer rapidement des éléments, utilisez LinkedList (mais ses performances de recherche sont très médiocres).

Afin d'effectuer la recherche la plus rapide, sur la base des données stockées dans un objet de collection, quelle collection dois-je utiliser?

Voici mon code:

    public void fillAndSearch(Collection<Student> collection) {
      if(collection!=null){
        for (int i=0; i<=10; i++) {
            Student student = new Student("name" + i, "id" + i);
            collection.add(student);
        }
      }
        //here We have to perform searching for "name7" or "id5",
        //then which implementation of collection will be fastest?
    }

class Student {
    String name;
    String id;

    Student(String name, String id) {
        this.name = name;
        this.id = id;
    }
} 
11
user4768611

Ce qui est souvent ignoré lors de la comparaison de ArrayList et LinkedList, ce sont les optimisations de gestion du cache et de la mémoire. ArrayList n'est en fait qu'un tableau, ce qui signifie qu'il est stocké dans un espace continu dans la mémoire. Cela permet au système d'exploitation d'utiliser des optimisations telles que "lorsqu'un octet en mémoire a été accédé, très probablement l'octet suivant sera accédé bientôt". De ce fait, ArrayList est plus rapide que LinkedList dans tous les cas sauf un: lors de l'insertion/suppression de l'élément au début de la liste (car tous les éléments du tableau doivent être décalés). L'ajout/la suppression à la fin ou au milieu, l'itération sur, l'accès à l'élément sont tous plus rapides en cas de ArrayList.

Si vous devez rechercher un étudiant avec un prénom et id, cela me semble être une carte avec une clé composite - Map<Student, StudentData>. Je recommanderais d'utiliser l'implémentation de HashMap, à moins que vous ayez besoin de pouvoir à la fois rechercher dans la collection et récupérer tous les éléments triés par clé, auquel cas TreeMap peut être une meilleure idée. N'oubliez pas que HashMap a O(1) temps d'accès, tandis que TreeMap a O(logn) temps d'accès.

Je ne sais pas trop ce que vous essayez de réaliser - pourquoi chercher dans cette collection? Que voulez-vous y trouver?

12
Jaroslaw Pawlak

Avec certaines restrictions, vous devez utiliser HashMap. Il vous donnera une recherche rapide, comme vous le souhaitiez.

Si vous vous souciez de parcourir les éléments dans un ordre spécifique, vous devez choisir TreeMap (ordre naturel) ou LinkedHashMap (ordre d'insertion).

Si votre collection est garantie immuable, vous pouvez utiliser une liste de tableaux triée avec une recherche binaire, cela vous fera économiser de la mémoire. Dans ce cas, vous pouvez rechercher uniquement par une clé spécifique, ce qui n'est pas souhaitable dans de nombreuses applications du monde réel.

Quoi qu'il en soit, vous devriez avoir vraiment énorme nombre d'éléments (millions/milliards) pour sentir la différence entre les solutions O(logN) et O(1) solutions.

Si vous souhaitez en savoir plus sur les structures de données, je vous recommande de consulter le cours Algorythms de l'université de Princeton sur coursera.com

2
AdamSkywalker

Il n'y a rien de mal à conserver plusieurs collections pour accéder plus rapidement à vos données.

Dans cette situation, j'utiliserais 2 HashMap<String, Student>. Un pour chaque clé de recherche.

(PS: ou si vous ne savez pas quel type de mot clé est utilisé pour la recherche, vous pouvez stocker les deux dans la même carte).

0
bvdb