Pourquoi java.util.Set n’a-t-il pas get (int index)?

Je suis sûr qu’il y a une bonne raison, mais est-ce que quelqu’un pourrait expliquer pourquoi l’interface java.util.Set ne dispose get(int Index) méthode get(int Index) ou d’une méthode get() similaire?

Il semble que les décors sont parfaits pour mettre les choses en place, mais je ne peux pas trouver une manière élégante de récupérer un seul élément.

Si je sais que je veux le premier élément, je peux utiliser set.iterator().next() , mais sinon, il semble que je set.iterator().next() lancer dans un tableau pour récupérer un élément à un index spécifique?

Quelles sont les manières appropriées de récupérer les données d’un ensemble? (autre que d’utiliser un iterator)

Je suis sûr que le fait qu’il soit exclu de l’API signifie qu’il y a une bonne raison pour ne pas le faire – est-ce que quelqu’un pourrait m’éclairer s’il vous plaît?

EDIT: Quelques très bonnes réponses ici, et quelques-unes disant “plus de contexte”. Le scénario spécifique était un test dbUnit, dans lequel je pouvais raisonnablement affirmer que le jeu renvoyé par une requête ne comportait qu’un élément et que j’essayais d’accéder à cet élément.

Cependant, la question est plus valable sans le scénario, car il rest plus ciblé:

Quelle est la différence entre set et list .

Merci à tous pour les réponses fantastiques ci-dessous.

Parce que les sets n’ont pas d’ordre. Certaines implémentations le font (en particulier celles implémentant l’interface java.util.SortedSet ), mais ce n’est pas une propriété générale des ensembles.

Si vous essayez d’utiliser des ensembles de cette manière, vous devriez envisager d’utiliser une liste à la place.

En fait, c’est une question récurrente lors de l’écriture d’applications JavaEE qui utilisent le mappage object-relationnel (par exemple avec Hibernate); et de toutes les personnes qui ont répondu ici, Andreas Petersson est le seul à avoir compris le véritable problème et à lui donner la bonne réponse: Java manque de UniqueList! (ou vous pouvez également l’appeler OrderedSet ou IndexedSet).

Maxwing a mentionné ce cas d’utilisation (dans lequel vous avez besoin de données ET commandées) et il a suggéré le SortedSet, mais ce n’est pas ce dont Marty Pitt avait vraiment besoin.

Ce “IndexedSet” N’EST PAS le même qu’un SortedSet – dans un SortedSet les éléments sont sortingés en utilisant un comparateur (ou en utilisant leur ordre “naturel”).

Mais à la place, il est plus proche d’un LinkedHashSet (que d’autres ont également suggéré), et plus encore d’un “ArrayListSet” (également inexistant), car il garantit que les éléments sont renvoyés dans le même ordre qu’ils ont été insérés.

Mais le LinkedHashSet est une implémentation, pas une interface! Ce qu’il faut, c’est une interface IndexedSet (ou ListSet ou OrderedSet ou UniqueList)! Cela permettra au programmeur de spécifier qu’il a besoin d’une collection d’éléments ayant un ordre spécifique et sans doublons, puis de l’instancier avec n’importe quelle implémentation (par exemple, une implémentation fournie par Hibernate).

Puisque JDK est open-source, cette interface sera peut-être finalement incluse dans Java 7 …

Il suffit d’append un point qui n’a pas été mentionné dans la réponse de mmyers .

Si je sais que je veux le premier élément, je peux utiliser set.iterator (). Next (), mais sinon, il semble que je doive lancer dans un tableau pour récupérer un élément à un index spécifique?

Quelles sont les manières appropriées de récupérer les données d’un ensemble? (autre que d’utiliser un iterator)

Vous devez également vous familiariser avec l’interface SortedSet (dont l’implémentation la plus courante est TreeSet ).

Un SortedSet est un ensemble (c.-à-d. Les éléments sont uniques) qui est ordonné par l’ ordre naturel des éléments ou en utilisant un Comparator . Vous pouvez facilement accéder aux premier et dernier éléments en utilisant les méthodes first() et last() . Un SortedSet est utile de temps en temps, lorsque vous devez conserver votre collection à la fois sans duplication et ordonnée d’une certaine manière.

Edit : Si vous avez besoin d’un ensemble dont les éléments sont conservés dans un ordre d’insertion (un peu comme une liste), consultez LinkedHashSet .

Cela conduit à la question de savoir quand vous devriez utiliser un ensemble et quand vous devriez utiliser une liste. Habituellement, le conseil va:

  1. Si vous avez besoin de données commandées, utilisez une liste
  2. Si vous avez besoin de données uniques, utilisez un ensemble
  3. Si vous avez besoin des deux, utilisez: un SortedSet (pour les données classées par comparateur) ou un OrderedSet / UniqueList (pour les données classées par insertion). Malheureusement, l’API Java n’a pas encore OrderedSet / UniqueList.

Un quasortingème cas qui apparaît souvent est que vous n’avez besoin ni de l’un ni de l’autre. Dans ce cas, vous voyez que certains programmeurs vont avec des listes et d’autres avec des ensembles. Personnellement, je trouve très nuisible de voir set comme une liste sans commander – parce que c’est vraiment une toute autre bête. À moins que vous ayez besoin de choses comme définir l’unicité ou définir l’égalité, privilégiez toujours les listes.

Je ne suis pas sûr si quelqu’un l’a bien expliqué, mais vous devez comprendre les éléments suivants:

Il n’y a pas de “premier” élément dans un ensemble.

Parce que, comme d’autres l’ont dit, les décors ne sont pas commandés. Un ensemble est un concept mathématique qui n’inclut pas spécifiquement la commande.

Bien sûr, votre ordinateur ne peut pas vraiment conserver une liste de choses qui ne sont pas commandées en mémoire. Il doit y avoir des commandes. En interne, c’est un tableau ou une liste liée ou quelque chose. Mais vous ne savez pas vraiment ce que c’est, et il n’y a pas vraiment de premier élément; l’élément qui sort “en premier” sort par hasard et pourrait ne pas être le premier la prochaine fois. Même si vous avez pris des mesures pour “garantir” un premier élément en particulier, cela se produit encore par hasard, car il vous est juste arrivé de bien faire les choses pour une implémentation particulière d’un ensemble; une implémentation différente peut ne pas fonctionner de cette façon avec ce que vous avez fait. Et, en fait, vous ne connaissez peut-être pas la mise en œuvre que vous utilisez aussi bien que vous le pensez.

Les gens courent dans ce ALL. LA. TEMPS. avec les systèmes SGBDR et ne comprend pas. Une requête SGBDR renvoie un ensemble d’enregistrements. C’est le même type d’ensemble de mathématiques: une collection non ordonnée d’éléments, seulement dans ce cas les éléments sont des enregistrements. Un résultat de requête SGBDR n’a aucun ordre garanti à moins que vous n’utilisiez la clause ORDER BY, mais tout le temps, les gens supposent qu’il le fait, puis se déclenchent un jour lorsque la forme de leurs données ou de leur code change légèrement et d’une manière différente et soudain, les résultats ne sortent pas dans l’ordre prévu. Ce sont généralement les personnes qui n’ont pas fait attention dans la classe de firebase database (ou lors de la lecture de la documentation ou des didacticiels) quand on leur a expliqué, dès le départ, que les résultats de la requête ne sont pas garantis.

certaines structures de données sont absentes des collections Java standard.

Bag (comme set mais peut contenir des éléments plusieurs fois)

UniqueList (liste ordonnée, peut contenir chaque élément une seule fois)

semble que vous auriez besoin d’une liste unique dans ce cas

Si vous avez besoin de structures de données flexibles, vous pourriez être intéressé par les collections Google

C’est vrai, l’élément dans Set n’est pas ordonné, par définition de la collection de jeux. Ils ne peuvent donc pas être accessibles par un index.

Mais pourquoi n’avons-nous pas une méthode get (object), pas en fournissant l’index comme paramètre, mais un object égal à celui que nous recherchons? De cette façon, nous pouvons accéder aux données de l’élément à l’intérieur de l’ensemble, simplement en connaissant ses atsortingbuts utilisés par la méthode égale.

Si vous allez effectuer de nombreux access aléatoires par index dans un ensemble, vous pouvez obtenir une vue de tableau de ses éléments:

 Object[] arrayView = mySet.toArray(); //do whatever you need with arrayView[i] 

Il y a deux inconvénients principaux:

  1. Ce n’est pas efficace en termes de mémoire, car un tableau pour l’ensemble doit être créé.
  2. Si l’ensemble est modifié, la vue devient obsolète.

En effet, Set ne garantit que l’unicité, mais ne dit rien sur les modèles d’access ou d’utilisation optimaux. Par exemple, un ensemble peut être une liste ou une carte, chacune ayant des caractéristiques de récupération très différentes.

La seule raison pour laquelle je peux penser à utiliser un index numérique dans un ensemble serait l’itération. Pour cela, utilisez

 for(A a : set) { visit(a); } 

Je me suis heurté à des situations où je voulais en fait un ensemble sortingé avec access via index (je suis d’accord avec d’autres affiches sur le fait que l’access à un ensemble non sortingé avec un index n’a aucun sens). Un exemple serait un arbre où je voulais que les enfants soient sortingés et que les enfants en double ne soient pas autorisés.

J’avais besoin de l’access via l’index pour les afficher et les atsortingbuts définis étaient utiles pour éliminer efficacement les doublons.

Ne trouvant aucune collection appropriée dans les collections java.util ou google, je l’ai trouvé simple à implémenter moi-même. L’idée de base est d’encapsuler un SortedSet et de créer une liste lorsque l’access via index est requirejs (et d’oublier la liste lorsque le SortedSet est modifié). Cela ne fonctionne bien sûr que lorsque vous changez le SortedSet encapsulé et que l’access à la liste est séparé dans la vie de la Collection. Sinon, il se comporte comme une liste souvent sortingée, c’est-à-dire trop lente.

Avec un grand nombre d’enfants, cela a beaucoup amélioré les performances par rapport à une liste que j’avais sortingée via Collections.sort.

Veuillez noter que seules 2 structures de données de base sont accessibles via index.

  • On peut accéder à la structure de données du tableau via un index avec une complexité temporelle O(1) pour obtenir un fonctionnement get(int index) .
  • La structure de données LinkedList peut également être accédée via index, mais avec une complexité temporelle O(n) pour obtenir le fonctionnement get(int index) .

En Java, ArrayList est implémenté en utilisant la structure de données Array .

Alors que la structure de données Set peut généralement être implémentée via la structure de données HashTable / HashMap ou BalancedTree , pour détecter rapidement si un élément existe et append un élément non existant, un Set bien implémenté peut atteindre la complexité O(1) . En Java, HashSet est l’ HashSet la plus utilisée de Set , elle est implémentée en appelant l’API HashMap , et HashMap est implémenté en utilisant un chaînage séparé avec des listes liées (une combinaison de Array et LinkedList ).

Puisque Set peut être implémenté via différentes structures de données, il n’y a pas de méthode get(int index) pour cela.

Vous pouvez faire une new ArrayList(set).get(index)

La raison pour laquelle l’ interface Set n’a pas d’appel de type get index ou même quelque chose de plus fondamental, comme first () ou last (), est due au fait qu’il s’agit d’une opération ambiguë et donc d’une opération potentiellement dangereuse. Si une méthode retourne un Set, et que vous appelez, dites la méthode first (), quel est le résultat attendu, étant donné qu’un Set générique ne donne aucune garantie sur la commande? L’object résultant peut très bien varier entre chaque appel de la méthode, ou peut ne pas vous donner une fausse impression de sécurité, jusqu’à ce que la bibliothèque que vous utilisez change la mise en œuvre en dessous et que tous vos codes soient rompus. sans raison particulière.

Les suggestions concernant les solutions de contournement répertoriées ici sont bonnes. Si vous avez besoin d’un access indexé, utilisez une liste. Soyez prudent avec l’utilisation d’iterators ou de toArray avec un ensemble générique, car a) il n’y a aucune garantie sur la commande et b) il n’y a aucune garantie que la commande ne changera pas avec les invocations suivantes ou avec différentes implémentations sous-jacentes. Si vous avez besoin de quelque chose entre un, SortedSet ou LinkedHashSet est ce que vous voulez.

// J’aimerais bien que l’interface Set ait un élément get-random-element.

java.util.Set est une collection d’éléments non ordonnés. Cela n’a aucun sens si l’ensemble a un get (int index), car Set n’a pas d’index et vous ne pouvez que deviner la valeur.

Si vous le voulez vraiment, codez une méthode pour obtenir un élément aléatoire de Set.

Si cela ne vous dérange pas que l’ensemble soit sortingé, vous pouvez être intéressé par le projet de carte indexée .

Le TreeSet / TreeMap amélioré permet d’accéder aux éléments par index ou d’obtenir l’index d’un élément. Et l’implémentation est basée sur la mise à jour des pondérations de nœuds dans l’arborescence RB. Donc, pas d’itération ou de sauvegarde par une liste ici.

Essayez ce code en tant qu’option alternative pour accéder aux index

 import java.io.*; import java.util.*; class GFG { public static void main (Ssortingng[] args) { HashSet  mySet=new HashSet(); mySet.add(100); mySet.add(100); int n = mySet.size(); Integer arr[] = new Integer[n]; arr = mySet.toArray(arr); System.out.println(arr[0]); } } 

Cela va imprimer 100.

Pour obtenir un élément dans un ensemble, j’utilise un suivant:

 public T getElement(Set set, T element) { T result = null; if (set instanceof TreeSet) { T floor = ((TreeSet) set).floor(element); if (floor != null && floor.equals(element)) result = floor; } else { boolean found = false; for (Iterator it = set.iterator(); !found && it.hasNext();) { if (true) { T current = it.next(); if (current.equals(element)) { result = current; found = true; } } } } return result; }