Obtenir cualquier d'un ensemble ou d'une collection peut sembler être une demande peu commune - voire arbitraire ou éclectique - mais elle est assez courante lorsqu'on a, par exemple, besoin de calculer statistiques sur les objets Keys ou Values d'une Map et doit initialiser les valeurs min/max . Le site cualquier d'un ensemble ou d'une collection (retourné par Map.keySet() ou Map.values()) sera utilisé pour cette initialisation avant la mise à jour des valeurs min/max au cours de l'année. chaque élément.
Alors, quelles sont les options dont on dispose lorsqu'on est confronté à ce problème et qu'on essaie en même temps de maintenir la mémoire et le temps d'exécution à un niveau bas et un code clair ?
Souvent, vous obtenez l'habituel : " convertir Set en ArrayList et récupérer le premier élément ". Génial ! Un autre tableau de plusieurs millions d'éléments et des cycles de traitement supplémentaires pour récupérer des objets de Set, allouer et remplir il :
HashMap<K,V> map;
List<K> list = new ArrayList<V>(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() ){ ... }
...
}
On peut aussi utiliser une boucle avec un Iterator, en utilisant un drapeau pour indiquer que min/max doivent être initialisés et une instruction conditionnelle pour vérifier si ce drapeau est activé pour toutes les itérations de la boucle. Cela implique beaucoup de vérifications conditionnelles.
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 faire l'initialisation en dehors de la boucle :
HashMap<K,V> 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 la peine de faire tout ce travail de la part du programmeur (et de configurer l'Iterator de la part de la JVM) chaque fois que min/max est nécessaire ?
La suggestion d'un vieux sportif qui a le sens de l'humour pourrait bien être : "Enveloppez votre carte dans une classe qui garde la trace des valeurs min et max lorsqu'elles sont ajoutées ou supprimées !
Il existe une autre situation qui, d'après mon expérience, n'a pas besoin de cualquier d'un élément de la carte se présente. C'est le cas lorsque la carte contient des objets qui ont une propriété commune - la même pour tous dans cette carte - et que vous devez lire cette propriété . Supposons, par exemple, qu'il existe une carte des bacs de retenue du même histogramme qui ont le même nombre de dimensions. Étant donné une telle carte, vous pouvez avoir besoin de connaître le nombre de dimensions de juste cualquier Histobin dans la carte afin, par exemple, de créer un autre Histobin de mêmes dimensions. Dois-je à nouveau configurer un itérateur et l'éliminer après avoir appelé next() une seule fois ? Je vais ignorer la suggestion de la personne javally-correcte pour cette situation.
Et si tous les problèmes pour obtenir le cualquier entraîne une augmentation insignifiante de la mémoire et des cycles du processeur, alors qu'en est-il de tout le code que l'on doit écrire juste pour obtenir l'information difficile à obtenir ? cualquier élément.
Nous avons besoin de la cualquier élément. Donnez-le nous !