Retrait du "premier" objet d'un ensemble
Dans certaines situations, j'ai besoin d'expulser le plus ancien élément dans une Java Set
. L'ensemble est mis en œuvre à l'aide d'un LinkedHashSet
ce qui le rend simple: il suffit de se débarrasser du premier élément retourné par l'ensemble de l'itérateur:
Set<Foo> mySet = new LinkedHashSet<Foo>();
//do stuff...
if (mySet.size() >= MAX_SET_SIZE)
{
Iterator<Foo> iter = mySet.iterator();
iter.next();
iter.remove();
}
C'est moche: 3 lignes pour faire quelque chose que je pourrait faire avec 1 ligne si j'ai été en utilisant un SortedSet
(pour d'autres raisons, un SortedSet
n'est pas une option ici):
if (/*stuff*/)
{
mySet.remove(mySet.first());
}
Donc, il y a une manière plus propre de le faire, sans:
- la modification de la
Set
mise en œuvre, ou - écrit statique méthode utilitaire?
Tout en tirant parti des solutions Goyave sont beaux.
je suis pleinement conscient que les jeux ne sont pas inhérentes à la commande. Je pose la question sur la suppression de la première entrée tel que défini par l'itération de l'ordre.
source d'informationauteur Matt Ball
Vous devez vous connecter pour publier un commentaire.
LinkedHashSet est un wrapper pour LinkedHashMap qui prend en charge une simple "supprimer les plus anciens" de la politique. Pour l'utiliser comme un Jeu, vous pouvez faire
semble être de moins de 3 lignes.
Vous devez synchroniser autour d'elle bien sûr, si votre jeu est partagé par plusieurs threads.
Si vous avez vraiment besoin de faire cela à plusieurs endroits dans votre code, il suffit d'écrire une méthode statique.
Les autres solutions proposées sont souvent plus lents car ils impliquent l'appel de la
Set.remove(Object)
méthode au lieu de laIterator.remove()
méthode.Avec la goyave:
Je vais également proposer une autre approche. Oui, il l'évolution de la mise en œuvre, mais pas de façon radicale: étendre
LinkedHashSet
et ont cette condition dans leadd
méthode:C'est toujours 5 ligne, mais il est invisible pour le code qui l'utilise. Et puisque c'est en fait un comportement spécifique de l'ensemble, il est logique de l'avoir dans le jeu.
Je pense que la façon dont vous le faites est bien. Est-ce quelque chose que vous faites assez souvent pour être vaut la peine de trouver une façon plus simple? Vous pourriez faire essentiellement la même chose avec la Goyave comme ceci:
Qui ajoute la faible surcharge d'emballage de la valeur et son itérateur pour limiter et puis l'appel de la
alwaysTrue()
prédicat une fois... ne semble pas spécialement la peine pour moi.Edit: De mettre ce que j'ai dit dans un commentaire en réponse à une question, vous pouvez créer un
SetMultimap
automatiquement restreint le nombre de valeurs qu'il peut avoir par clé comme ceci:Rapide et sale une solution en ligne:
mySet.remove(mySet.toArray(new Foo[mySet.size()])[0])
😉Cependant, je préfère encore aller pour l'itérateur solution, car ce serait plus lisible et devrait également être plus rapide.
Edit: j'irais pour Mike Samuel solution. 🙂