2017-04-20 3 views
1

J'ai un HashMap qui a la valeur Object. Je veux trouver non. de toutes ces occurrences de Object en valeur HashMap qui a une certaine valeur de propriété définie. Ex. mentionnés ci-dessous:Un moyen efficace de trouver non des occurrences de certaines valeurs de propriété dans l'objet comme valeur de hashmap

class Employee{ 
    private String name; 

    public String getName(){ 
    return name; 
    } 

    public void setName(String name){ 
    this.name = name; 
    } 
} 
Map<Integer, Employee> emp = new HashMap<Integer, Employee>(); 

emp.add(1, E1); 
emp.add(2, E2); 

Je veux trouver le nombre d'occurrences dans hashmap où name = "robert". quel est le moyen le plus efficace de le faire. Puis-je le faire sans boucles car mon haschmap est très grand.

Répondre

0

Je ne pense pas que ce soit possible, sauf si vous créez une sorte d'ordre. Par exemple si vous mettez vos noms où les clés sont dans l'ordre croissant, et les valeurs sont dans l'ordre lexicographique, vous pouvez mettre et obtenir le nom dans l'ordre avec une complexité de O (log2 (n)) avec un algorithme de recherche bynaire.

Autre solution est de sauver dinamically dans une autre structure de ce genre d'information pour obtenir plus rapidement, comme une carte de hachage où les clés sont les noms et les valeurs sont les occurrences

espère que cette aide

2

Répondre à la sans boucles partie, pas tellement le manière la plus efficace partie: vous pouvez le faire sans boucles en utilisant Java 8 Streams mais cela ne le rend pas plus efficace en soi.

Il est théoriquement possible que la parallélisation puisse aider si la carte est vraiment grande. Bien que dans ce cas, il est peu probable que le prédicat filter soit vraiment bon marché.

Quoi qu'il en soit, la parallélisation serait facile à réaliser avec Java 8 Streams. En supposant que votre classe d'employés a une méthode getName(), vous pouvez essayer quelque chose comme ça

Map<Integer, Employee> emp = new HashMap<Integer, Employee>(); 

String name = "robert"; 

long count = emp.values() 
     .parallelStream() 
     .filter(e -> name.equals(e.getName())) 
     .count(); 

Modifier:

Il semble que j'étais un peu trop pessimiste en ce qui concerne les améliorations d'exécution potentielles en raison de parallèles flux. J'ai fait un petit test sur un I7 quad-core avec une HashMap contenant 750 000 entrées.

L'amélioration par rapport à l'approche en boucle for était systématiquement d'environ 50%. C'est à dire si (et seulement si!) Vous dou encore et encore, en moyenne, vous pourriez doubler votre vitesse de traitement.

0

une approche simple, vous pouvez essayer (mais pas le meilleur)

String name = "robert"; 
int count = 0; 
for(Employee theEmployee: emp.values()) { 
    if (theEmployee.getName().equals(name)) { 
     count++; 
    } 
} 

EDIT: J'ai remarqué quelque chose dans votre code -> vous ajoutez au hashmap comme celui-ci

emp.put(1, E1); 
emp.put(2, E2); 
emp.put(3, E3); 

PAS

emp.add(1, E1); 
emp.add(2, E2); 
emp.add(3, E3); 
+0

que l'ajout était juste pour la référence. Non utilisé dans le code actuel. Mais dans la réponse proposée ci-dessus, encore la boucle for va. Comment puis-je éviter de faire des loopings car mon Hashmap est très grand? – Ashutosh