11
votes

Est-ce que les collectors.Toset () renvoie toujours un hashset? Quel est le contrat?

Javadoc dit

retourne un collecteur qui accumule les éléments d'entrée dans une nouvelle Régler. Il n'y a pas de garantie sur le type, la mutabilité, la sérialisalisabilité, ou le fil-sécurité de l'ensemble renvoyé; Si plus de contrôle sur le Un ensemble retourné est requis, utiliser tossollection (java.util.function.supplier).

SO COLLECTEURS.TOCOLLECTION (HASHSET :: NOUVEAU) semble être une bonne idée d'éviter les problèmes ici ( Donc, question ).

Mon problème est, aussi difficile que j'ai essayé, je ne peux rien obtenir d'autre retour de Toset ( ) qu'un hashset

Voici le code que j'ai utilisé: xxx

pourquoi alors, le Javadoc indiquer qu'il n'y a pas de garantie en fait, il y a ...


11 commentaires

hashset :: Nouveau est actuellement codé dur comme le fournisseur pour le fichier défini (et cela explique votre résultat). Mais rien ne garantit que cela ne changera pas dans une version future.


Pourquoi le garantiraient-ils? Ne pas définir le comportement leur donne la liberté de le changer si elles décident que quelque chose d'autre fonctionne mieux.


"Pas garanti" ne signifie pas "choisi au hasard" ...


@Sashasalauyou Non. Ils peuvent renvoyer différentes implémentations définies. Op n'a jamais prétendre qu'il est aléatoire.


@Tunaki ok je comprends ça. En effet, je suis allé vérifier la source et elle est codée en papier. C'est certainement ma compréhension des nuances anglaises.


@SashasalauYou La question n'est pas sage de code mais plus javadoc sage. Ma question était plus "pourquoi ont-ils écrit ça?". Mais comme je l'ai dit, c'est ma compréhension de l'anglais qui est à blâmer ici.


@Yassinhajaj côté note: i ++ <1_000_000; est un peu bizarre. Bien sûr, c'est intelligent, mais cela ne sauve aucun espace plus d'espace que i <1_000_000; I ++ , qui est la forme que la plupart des gens ont tendance à s'attendre. Si vous codez dans un projet avec d'autres personnes, je vous suggère d'essayer de garder vos boucles simples et aussi faciles à comprendre que possible. Si vous codez vous-même, allez à l'état sauvage.


@Jeffrey Bonjour Jeffrey, merci. Oui, je voulais juste tester la théorie et je voulais écrire plus vite et m'assurer que je recevais assez de boucles lol. Je sais que ce n'est pas recommandé :).


Le Javadoc est principalement sur Spécification ; Il dit ce que la classe ou la méthode doit faire et ce que l'utilisateur peut compter sur. Une spécification claire - séparément de la mise en œuvre - les lecteurs avantages, en leur disant ce qu'ils peuvent compter et maintenus en leur disant quelles promesses ont été apportées aux utilisateurs (et donc quelle flexibilité qu'ils doivent évoluer ou recréer la mise en œuvre. ) Toute mise en œuvre donnée, presque par définition, sera plus spécifique, c'est pourquoi nous écrivons des spécifications distinctes - de sorte que vous ne vous fallons pas sur des caractéristiques accidentelles de la mise en œuvre.


Dupliqué possible de Qu'est-ce que cela signifie de programmer à une interface? < / a>


@Jeffrey: En fait, ce n'est pas la même chose que pour (...; i ++ <1_000_000;) traitera la valeur 1_000_000 pendant que pour (...; i <1_000_000 ; i ++) ne le fera pas. C'est pourquoi de telles constructions non intuitives doivent être évitées, en utilisant pour (...; i <= 1_000_000; i ++) est plus facile à reconnaître ...


5 Réponses :


15
votes

Les états Javadoc Il n'y a pas garantie , mais cela n'empêche aucune implémentation spécifique de revenir toujours un type d'ensemble spécifique. Ceci est juste que les concepteurs disent qu'ils ne veulent pas limiter à quoi une future mise en œuvre peut faire. Il ne dit rien de ce que la mise en œuvre actuelle fait réellement.

En d'autres termes, vous avez découvert implémentation définie comportement (renvoyer toujours un hashset ), mais si vous comptez sur cela, vous pouvez avoir des problèmes à l'avenir.


1 commentaires

Merci Jim. C'est bien une perspective que je ne pensais pas. Ma compréhension de l'anglais est de blâmer ici, je pense.




5
votes

La mise en œuvre de l'openJDK actuelle (et Afaik, Oracle's Trop) renvoie toujours toujours un hashset - mais il n'y a pas garantie de cela. Une version future du JDK peut très bien modifier ce comportement et vous casser votre code si vous supposez en quelque sorte que collectors.toset () retournera un hashset (par exemple, explicitement bas- jeter).


0 commentaires

1
votes

Je pense que ce que vous cherchez est ceci: Collecteurs.Tocollection (LinkedHashSet :: Nouveau)


0 commentaires

4
votes

Les futures versions Java pourraient, par exemple, renvoyer des implémentations spécialisées immuables définies qui sont plus efficaces pour la lecture et la consommation moins de mémoire que la mise en œuvre actuelle HASHSET , qui n'est vraiment qu'un wrapper autour de HASHMAP . Projet Valhalla peut éventuellement entraîner de telles optimisations.

Ils pourraient même choisir de renvoyer différents types de paramètres en fonction de la quantité de données, par ex. Un ensemble vide ou singleton si elle sait à l'avance que seuls zéro ou un élément seront retournés.

Donc, en donnant moins de garanties que possible sur la base de la mise en œuvre actuelle, elles maintiennent la porte ouverte aux améliorations futures.


0 commentaires