Bon moyen d’obtenir * n’importe quelle valeur * d’un ensemble Java?

Étant donné un simple Set , quel est le bon moyen (rapide, peu de lignes de code) pour obtenir une valeur quelconque de l’ Set ?

Avec une List , c’est facile:

 List things = ...; return things.get(0); 

Mais, avec un Set , il n’y a pas de .get(...) car les Set ne sont pas ordonnés.

Un Set est un Iterable , donc itérant au premier élément fonctionne:

 Set things = ...; return things.iterator().next(); 

Guava a une méthode pour le faire, bien que l’extrait ci-dessus soit probablement meilleur .

Obtenir un élément d’un ensemble ou d’une collection peut sembler inhabituel – sinon arbitraire ou éclectique – mais il est assez courant, par exemple, de calculer des statistiques sur des objects clés ou valeurs dans une carte et d’initialiser min / valeurs max . Tout élément d’un ensemble / collection (renvoyé par Map.keySet () ou Map.values ​​()) sera utilisé pour cette initialisation avant la mise à jour des valeurs min / max sur chaque élément.

Alors, quelles options a-t-on face à ce problème et en même temps essayer de garder la mémoire et le temps d’exécution réduits et le code clair?

Souvent, vous obtenez l’habituel: ” Convertissez Set en ArrayList et obtenez le premier élément “. Génial! Un autre ensemble de millions d’éléments et de cycles de traitement supplémentaires pour récupérer des objects de Set, allouer un tableau et le remplir :

 HashMap map; List list = new ArrayList(map.keySet()); // min/max of keys min = max = list.get(0).some_property(); // initialisation step for(i=list.size();i-->1;){ if( min > list.get(i).some_property() ){ ... } ... } 

Ou bien on peut utiliser une boucle avec un iterator, en utilisant un drapeau pour indiquer que min / max doit être initialisé et une instruction conditionnelle pour vérifier si cet indicateur est défini pour toutes les itérations de la boucle. Cela implique beaucoup de vérification conditionnelle.

 boolean flag = true; Iterator it = map.keySet().iterator(); while( it.hasNext() ){ if( flag ){ // initialisation step min = max = it.next().some_property(); flag = false; } else { if( min > list.get(i).some_property() ){ min = list.get(i).some_property() } ... } } 

Ou faites l’initialisation en dehors de la boucle:

 HashMap map; Iterator it = map.keySet().iterator(); K akey; if( it.hasNext() ){ // initialisation step: akey = it.next(); min = max = akey.value(); do { if( min > list.get(i).some_property() ){ min = akey.some_property() } } while( it.hasNext() && ((akey=it.next())!=null) ); } 

Mais est-ce que cela vaut vraiment toute cette manœuvre de la part du programmeur (et la mise en place de l’iterator au nom de la JVM) chaque fois que min / max est nécessaire?

La suggestion d’un sport “à la javale” pourrait bien être: “Enveloppez votre carte dans une classe qui garde trace des valeurs min et max quand elle est placée ou supprimée!”.

Il y a une autre situation dans laquelle, selon moi, le besoin de n’importe quel élément d’une carte se pose. C’est à ce moment que la carte contient des objects qui ont une propriété commune – tous identiques pour tous sur cette carte – et vous devez lire cette propriété . Par exemple, supposons qu’il existe une carte de stockage des mêmes histogrammes qui ont le même nombre de dimensions. Étant donné une telle carte, vous devrez peut-être connaître le nombre de dimensions de n’importe quelle histobine dans la carte pour, par exemple, créer une autre histobine de mêmes dimensions. Dois-je réinstaller un iterator et le supprimer après avoir appelé next () une seule fois? Je vais sauter la suggestion de la personne javally-correcte à cette situation.

Et si toute la difficulté à obtenir l’élément any entraîne une augmentation négligeable de la mémoire et des cycles du processeur, alors qu’en est-il de tout le code qu’il faut écrire pour obtenir un élément difficile à obtenir.

Nous avons besoin de n’importe quel élément. Donnez-le nous!

Comme les stream sont présents, vous pouvez également le faire, mais vous devez utiliser la classe java.util.Optional . Optional est une classe wrapper pour un élément ou explicitement no-element (en évitant le pointeur nul).

 //returns an Optional. Optional  optT = set.stream().findAny(); //Optional.isPresent() yields false, if set was empty, avoiding NullpointerException if(optT.isPresent()){ //Optional.get() returns the actual element return optT.get(); }