web-dev-qa-db-fra.com

Comment trier un HashSet?

Pour les listes, nous utilisons la méthode Collections.sort(List). Et si on veut trier une HashSet?

85
Diana

Un HashSet ne garantit aucune commande de ses éléments. Si vous avez besoin de cette garantie, envisagez d'utiliser un TreeSet pour contenir vos éléments.

Cependant, si vous avez juste besoin que vos éléments soient triés pour cette occurrence, créez simplement une liste et triez-la temporairement:

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);
97
isak gilbert

Utilisez Java.util.TreeSet comme objet réel. Lorsque vous parcourez cette collection, les valeurs sont renvoyées dans un ordre bien défini.

Si vous utilisez Java.util.HashSet alors l'ordre dépend d'une fonction de hachage interne qui n'est presque certainement pas lexicographique (basée sur le contenu).

14
P45 Imminent

Vous pouvez utiliser un TreeSet à la place.

12
jcarvalho

Java 8 pour trier ce serait:

fooHashSet.stream()
  .sorted(Comparator.comparing(Foo::getSize)) //comparator - how you want to sort it
  .collect(Collectors.toList()); //collector - what you want to collect it to

* Foo::getSize c'est un exemple montrant comment trier naturellement le HashSet de YourItem par taille.

* Collectors.toList() va collecter le résultat du tri dans une liste dont vous aurez besoin pour le capturer avec List<Foo> sortedListOfFoo =

11
LazerBanana

Vous pouvez utiliser Java 8 collectionneurs et TreeSet

list.stream().collect(Collectors.toCollection(TreeSet::new))

5
Ninja

Vous pouvez utiliser TreeSet comme mentionné dans d'autres réponses.

Voici un peu plus d'explications sur la façon de l'utiliser:

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

Sortie:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3
4
Alisa

Les éléments de HashSet ne peuvent pas être triés. Chaque fois que vous insérez un élément dans HashSet, les compartiments entiers seront gâchés. La bonne chose à ce sujet est l'efficacité dans la performance.

TreeSet va trier tous les éléments automatiquement chaque fois que vous insérez un élément.

Peut-être que ce que vous essayez de faire est de trier une seule fois. Dans ce cas, TreeSet n'est pas la meilleure option car il doit déterminer à tout moment l'emplacement des nouveaux éléments ajoutés.

La solution la plus efficace consiste à utiliser ArrayList. Créez une nouvelle liste et ajoutez tous les éléments, puis triez-la une fois. Si vous souhaitez ne conserver que des éléments uniques (supprimez tous les doublons comme le fait l'ensemble, puis placez la liste dans un LinkedHashSet, la commande que vous avez déjà triée sera conservée).

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

Maintenant, vous avez un ensemble trié si vous le voulez sous forme de liste, puis convertissez-le en liste.

2
off99555

À mon humble avis, la réponse de LazerBanana devrait être la réponse la mieux notée et acceptée, car toutes les autres réponses pointant vers Java.util.TreeSet (ou converties en liste puis appelant Collections.sort(...) sur la liste convertie) ne sont pas gênées demandez à OP quel type d’objets votre HashSet a, c’est-à-dire si ces éléments ont une valeur prédéfinie ordre naturel ou non & ce n’est pas une question facultative, mais une question obligatoire.

Vous ne pouvez pas entrer et commencer à mettre vos éléments HashSet dans une interface TreeSet si le type d'élément n'implémente pas déjà l'interface Comparable ou si vous ne passez pas explicitement Comparator to TreeSet constructeur.

De TreeSet JavaDoc,

Construit un nouvel ensemble d'arbres vides, triés selon l'ordre naturel de ses éléments. Tous les éléments insérés dans l'ensemble doivent implémenter l'interface Comparable. En outre, tous ces éléments doivent être comparables entre eux: e1.compareTo (e2) ne doit pas émettre d’exception ClassCastException pour les éléments e1 et e2 de l’ensemble. Si l'utilisateur tente d'ajouter un élément à l'ensemble qui ne respecte pas cette contrainte (par exemple, il essaie d'ajouter un élément de chaîne à un ensemble dont les éléments sont des entiers), l'appel add générera une exception ClassCastException.

C’est pourquoi seules les réponses basées sur les flux Java8 - pour lesquelles vous définissez votre comparateur sur place - n’ont de sens que parce que l’implémentation de comparable dans POJO devient facultative. Le programmeur définit le comparateur au besoin. Essayer de collecter dans TreeSet sans poser cette question fondamentale est également incorrect (réponse de Ninja). En supposant que les types d'objet soient String ou Integer est également incorrect.

Cela dit, d’autres préoccupations telles que,

  1. Performance de tri
  2. Empreinte mémoire (conserver l’original et créer de nouveaux ensembles chaque fois que vous triez ou souhaitez trier l’ensemble sur place, etc.)

devrait être les autres points pertinents aussi. Le simple fait de pointer sur l'API ne devrait pas être uniquement une intention.

Étant donné que l'ensemble d'origine contient déjà uniquement nique éléments, cette contrainte est également conservée par l'ensemble trié. Par conséquent, l'ensemble d'origine doit être effacé de la mémoire car les données sont dupliquées.

2
Sabir Khan
1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    s.add("ved");
    s.add("prakash");
    s.add("sharma");
    s.add("Apple");
    s.add("ved");
    s.add("banana");
    System.out.println("Before Sorting");
    for (String s1 : s) {
        System.out.print("  " + s1);
    }

    System.out.println("After Sorting");
    al.addAll(s);
    Collections.sort(al);
    for (String set : al) {
        System.out.print(" " + set);
    }
  }
 }

entrée - ved prakash sharma Apple ved banana

Sortie - Apple prakash à la banane partagé

1
Ved Prakash

Nous ne pouvons pas décider que les éléments d'un HashSet seraient triés automatiquement. Mais nous pouvons les trier en les convertissant en TreeSet ou n'importe quelle liste comme ArrayList ou LinkedList etc.

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");
0
alexvipul
0
taha

vous pouvez le faire des manières suivantes:

Méthode 1:

  1. Créer une liste et y stocker toutes les valeurs de hachage
  2. trier la liste en utilisant Collections.sort ()
  3. Stockez la liste dans LinkedHashSet car elle conserve l'ordre d'insertion

Méthode 2:

  • Créez un treeSet et stockez-y toutes les valeurs.

La méthode 2 est préférable, car l’autre méthode prend beaucoup de temps pour transférer les données entre le hachage et la liste.

0
Sujit

Vous pouvez utiliser la bibliothèque de goyave pour le même

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});
0
Ankita Bhowmik