HashSet mit Comparable sortieren

jerevat

Mitglied
Hallo,

gegeben ist ein HashSet<String> dessen Strings wie folgt aussehen: "stringValue_longValue".
Anhand der longValue soll das HashSet sortiert werden.
Also dachte ich mir eine erweiterte HashSet-Klasse mit der Schnittstelle Comparable zu entwickeln:
Java:
public class HashSetEx extends HashSet<String> implements Comparable<Long>
Was mich dabei verwirrt, ist, was kann ich hier womit vergleichen, wenn mir doch nur this.toString() zur Verfügung steht?
Das this.toString ist nicht einfach nur ein Element, sondern eine Art Array.
Ist das überhaupt der richtige Ansatz für mein Vorhaben?
 
Beste Antwort
Ich versuche mal B, die Stream.sort() Funktion anzuwenden.
Das einfach einmal schnell aufgebaut, wie das dann mit dem sorted(Comparator) aussehen könnte:
Java:
import java.util.Comparator;
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet<String> myHashSet = new HashSet<>();
        myHashSet.add("a_5");
        myHashSet.add("b_1");
        myHashSet.add("c_7");
        myHashSet.add("d_2");

        myHashSet.stream()
                .sorted(Comparator.comparingLong(s -> getLongValue(s)))
                .forEach(System.out::println);
    }

    public static long getLongValue(String value) {
        String[] splited = value.split("_");
        return...

Oneixee5

Top Contributor
You make my day ... !

Eine Sortierung von HashSet ist nicht möglich. Die Elemente des HashSet können jedoch indirekt sortiert werden, indem sie in List oder TreeSet umgewandelt werden, aber dadurch bleiben die Elemente im Zieltyp statt im HashSet-Typ.
 

KonradN

Super-Moderator
Mitarbeiter
Da erst einmal ein paar wichtige Grundlagen:

a) Was genau willst Du sortieren? Und dann sind die ja Strings, die in einem bestimmten Format sind. Daher ist es ein Comparable<String> bzw. ein Comparator<String>, den Du implementieren willst.

b) Ein HashSet ist nicht sortiert. Aber Du kannst natürlich de Elemente eines HashSet sortieren. Das ginge z.B. per Stream - also myHashSet.stream().sort(comparator).... - Am Ende kannst Du es in eine List bringen oder so.
Aber wenn die Elemente generell sortiert sein sollen, dann ist der gewählte Datentyp evtl. falsch. Vielleicht willst du statt einer HashSet eine TreeSet haben? Dann kannst Du einen Comparator mit festlegen und Du hast die Elemente immer sortiert.

c) Wähle vernünftige Datentypen! Deine Strings haben ja ganz offensichtlich einen bestimmten Inhalt: Einen String Anteil und einen long Anteil. Da würde es also Sinn machen, das auch entsprechend in einer entsprechenden Klasse zu speichern (Einfach mal quick & dirty etwas zusammen geschrieben. Fehlerbehandlung ist noch nicht super, aber es zeigt, worauf ich hinaus will:
Java:
import org.jetbrains.annotations.NotNull;

import java.util.Comparator;

public class MyDataType implements Comparable<MyDataType> {
    private String stringPart;
    private long longPart;

    public MyDataType(String stringPart, long longPart) {
        this.stringPart = stringPart;
        this.longPart = longPart;
    }

    public MyDataType() {
    }

    public String getStringPart() {
        return stringPart;
    }

    public void setStringPart(String stringPart) {
        this.stringPart = stringPart;
    }

    public long getLongPart() {
        return longPart;
    }

    public void setLongPart(long longPart) {
        this.longPart = longPart;
    }

    @Override
    public String toString() {
        return stringPart + "_" + longPart;
    }
    
    public static MyDataType fromString(String string) {
        if (string == null || !string.contains("_"))
            throw new RuntimeException("Not a valid string!");
        
        String[] parts = string.split("_");
        return new MyDataType(parts[0], Long.parseLong(parts[1]));
    }

    @Override
    public int compareTo(@NotNull MyDataType other) {
        return Long.compare(longPart, other.longPart);
    }
}

Das wäre dann etwas, das in einem TreeSet mit der natural Order wie gewünscht sortiert wäre.
 

jerevat

Mitglied
You make my day ... !

Eine Sortierung von HashSet ist nicht möglich. Die Elemente des HashSet können jedoch indirekt sortiert werden, indem sie in List oder TreeSet umgewandelt werden, aber dadurch bleiben die Elemente im Zieltyp statt im HashSet-Typ.
Eine Liste oder ein TreeSet() sortieren nach dem Alphabet oder nach einem Zahlenwert, je nach Inhalt.
Bei mir besteht der String aus einem Text, einem Unterstrich als Trenner / Separator und einem long-Zahlenwert (= Datum in Millisekunden):
Java:
stringVar = "abc_12345678910111213"
Ich möchte diese HashSet-Strings splitten, nach dem Datumswert sortieren und diese Änderung im HashSet so übernehmen
 

jerevat

Mitglied
b) Ein HashSet ist nicht sortiert. Aber Du kannst natürlich de Elemente eines HashSet sortieren. Das ginge z.B. per Stream - also myHashSet.stream().sort(comparator).... - Am Ende kannst Du es in eine List bringen oder so.
Aber wenn die Elemente generell sortiert sein sollen, dann ist der gewählte Datentyp evtl. falsch. Vielleicht willst du statt einer HashSet eine TreeSet haben? Dann kannst Du einen Comparator mit festlegen und Du hast die Elemente immer sortiert.

c) Wähle vernünftige Datentypen! Deine Strings haben ja ganz offensichtlich einen bestimmten Inhalt: Einen String Anteil und einen long Anteil. Da würde es also Sinn machen, das auch entsprechend in einer entsprechenden Klasse zu speichern (Einfach mal quick & dirty etwas zusammen geschrieben. Fehlerbehandlung ist noch nicht super, aber es zeigt, worauf ich hinaus will
Ich versuche mal B, die Stream.sort() Funktion anzuwenden.
Ansonsten wird es wohl auf C, einen "eigenen Datentypen" hinauslaufen.
 

KonradN

Super-Moderator
Mitarbeiter
Ich versuche mal B, die Stream.sort() Funktion anzuwenden.
Das einfach einmal schnell aufgebaut, wie das dann mit dem sorted(Comparator) aussehen könnte:
Java:
import java.util.Comparator;
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet<String> myHashSet = new HashSet<>();
        myHashSet.add("a_5");
        myHashSet.add("b_1");
        myHashSet.add("c_7");
        myHashSet.add("d_2");

        myHashSet.stream()
                .sorted(Comparator.comparingLong(s -> getLongValue(s)))
                .forEach(System.out::println);
    }

    public static long getLongValue(String value) {
        String[] splited = value.split("_");
        return Long.parseLong(splited[1]);
    }
}
 
Beste Antwort

mrBrown

Super-Moderator
Mitarbeiter
Eine Liste oder ein TreeSet() sortieren nach dem Alphabet oder nach einem Zahlenwert, je nach Inhalt.
Bei mir besteht der String aus einem Text, einem Unterstrich als Trenner / Separator und einem long-Zahlenwert (= Datum in Millisekunden):
Java:
stringVar = "abc_12345678910111213"
Ich möchte diese HashSet-Strings splitten, nach dem Datumswert sortieren und diese Änderung im HashSet so übernehmen
TreeSet können beliebig sortieren, je nachdem was du zum Vergleichen benutzt, und List kann man natürlich auch beliebig sortieren - und anders als bei HashSets ist es bei den beiden überhaupt möglich, diese zu sortieren. Ein HashSet ist immer ungeordnet!
 

Oneixee5

Top Contributor
Eine Liste oder ein TreeSet() sortieren nach dem Alphabet oder nach einem Zahlenwert, je nach Inhalt.
Bei mir besteht der String aus einem Text, einem Unterstrich als Trenner / Separator und einem long-Zahlenwert (= Datum in Millisekunden):
Java:
stringVar = "abc_12345678910111213"
Ich möchte diese HashSet-Strings splitten, nach dem Datumswert sortieren und diese Änderung im HashSet so übernehmen
Der Punkt ist: Warum ist der String so aufgebaut? Machst du das selbst? Man könnte eine Klasse verwenden, welche den String– und long–Wert getrennt verwaltet. Dann wäre so etwas sehr leicht zu handhaben.
 

jerevat

Mitglied
Das einfach einmal schnell aufgebaut, wie das dann mit dem sorted(Comparator) aussehen könnte:
Fast gleich:

Java:
final String ID_SEPARATOR = "_";
Set<String> _channelIdList = new HashSet<>();

private void sortChannelIds() {
    _channelIdList = _channelIdList.parallelStream()
    .sorted(Comparator.comparingLong(this::getMilliseconds))
    .collect(Collectors.toCollection(LinkedHashSet::new));
}

private long getMilliseconds(String value) {
    return Long.valueOf(value.split(ID_SEPARATOR)[5]);
}

Es sortiert auf jeden Fall richtig.
 

jerevat

Mitglied
TreeSet können beliebig sortieren, je nachdem was du zum Vergleichen benutzt, und List kann man natürlich auch beliebig sortieren - und anders als bei HashSets ist es bei den beiden überhaupt möglich, diese zu sortieren. Ein HashSet ist immer ungeordnet!
Ich kann auf das (Hash)Set nicht verzichten, da ich diese Struktur zum Speichern von Daten mittels SharedPreferences() in Android benötige.
 

KonradN

Super-Moderator
Mitarbeiter
Ich kann auf das (Hash)Set nicht verzichten, da ich diese Struktur zum Speichern von Daten mittels SharedPreferences() in Android benötige.
Kannst Du das evtl. etwas erläutern? Du bekommst also bereits ein HashSet von einer Android Methode? Wenn Du nur generell ein Set brauchst: TreeSet ist auch ein Set! Nur eben im Gegensatz zu dem HashSet hast Du bei dem TreeSet noch zusätzlich die Sortierung.
 

jerevat

Mitglied
Kannst Du das evtl. etwas erläutern? Du bekommst also bereits ein HashSet von einer Android Methode?
Für die Android-Benachrichtigungen generiere ich entsprechende Channel-Ids, die aus kurzen Texten und Zahlen - durch einen Separator getrennt - zusammengesetzt sind.
Diese IDs kommen in die HashSet<String> Auflistung, weil sich Objekte dieser Klasse mittels SharedPreferences() speichern und laden lassen.
Da die Anzahl der IDs überschaubar ist, bin ich auf eine lokale Datenbank nicht angewiesen und kann diese Auflistung gemeinsam mit den Einstellungswerten der App in eine XML hinterlegen.
Bevor ich die Frage hier gestellt habe, habe ich mit der TreeSet-Klasse herumprobiert.
Damit konnte ich zwar neue IDs in jenen Moment richtig ordnen, die vorherigen haben sich jedoch nicht angesprochen gefühlt und blieben am Ende gelistet.
Weil das nicht ganz zielführend war, wollte ich eine eigene Set-Klasse mit einer Sortierfunktion, die noch mehr Fragen aufwarf. Und so landete ich hier.
 

KonradN

Super-Moderator
Mitarbeiter
Dann sollte es aus meiner Sicht kein Problem sein, das HashSet durch ein TreeSet zu ersetzen. Dann hättest Du die Sortierung in der Datenstruktur mit drin.
 

jerevat

Mitglied
Dann sollte es aus meiner Sicht kein Problem sein, das HashSet durch ein TreeSet zu ersetzen. Dann hättest Du die Sortierung in der Datenstruktur mit drin.
So geht es auch:
Java:
final String ID_SEPARATOR = "_";

Set<String> _channelIdList = new TreeSet<>((o1, o2) -> {
    Long l1 = Long.valueOf(o1.split(ID_SEPARATOR)[5]);
    Long l2 = Long.valueOf(o2.split(ID_SEPARATOR)[5]);
    return l1.compareTo(l2);
});
Im Anschluss das Set mit Daten / Strings füllen und alles wird automatisch (von klein nach groß) sortiert.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Geht collections.sort bei allen? Linkedhashset, ArrayList, HashSet etc. Java Basics - Anfänger-Themen 4
volcanos HashSet und Iterator -> Falsche Sortierreihenfolge ? Java Basics - Anfänger-Themen 18
D Erste Schritte Code verstehen - HashSet Java Basics - Anfänger-Themen 8
J Hashset Java Basics - Anfänger-Themen 13
J HashSet Methode contains liefert false (hash Methode überschrieben) Java Basics - Anfänger-Themen 3
W Element aus HashSet in String umformen Java Basics - Anfänger-Themen 7
T HashSet in List-Object Java Basics - Anfänger-Themen 5
C Auf einzelne Werte aus HashSet zugreifen Java Basics - Anfänger-Themen 10
J Klassen HashSet, TreeSet: unregelmäßige Zahlenreihen beim Befüllen Java Basics - Anfänger-Themen 7
T Methoden HashSet Objekt mit Zufallszahlen befüllen Java Basics - Anfänger-Themen 3
J Verstehe meine HashSet Ausgabe nicht Java Basics - Anfänger-Themen 5
W Verknüpfung von Räumen mit Hashset Java Basics - Anfänger-Themen 10
J HashSet contain Methode funktioniert nicht wie gewollt Java Basics - Anfänger-Themen 7
M Collections HashSet verständnisproblem Java Basics - Anfänger-Themen 9
R Hashset.add(Array) liefert immer true? Java Basics - Anfänger-Themen 23
Mrtwomoon Collections Hashset elemente ohne Eckigeklammer ausgeben Java Basics - Anfänger-Themen 9
M Collections Problem bei Überschreibung von hashcode() und equals() bei Hashset-Implementierung Java Basics - Anfänger-Themen 5
A Elemente in HashSet enthalten oder nicht Java Basics - Anfänger-Themen 6
A HashSet (oder besser geignetes) Java Basics - Anfänger-Themen 14
T Hashset - Allgemeine Fragen Java Basics - Anfänger-Themen 19
J So ähnlich wie HashSet Java Basics - Anfänger-Themen 2
D HashSet vs Liste Java Basics - Anfänger-Themen 5
T HashSet Java Basics - Anfänger-Themen 3
F suche Elemente in HashSet Java Basics - Anfänger-Themen 5
E Collections HashSet - Ausgabe sortiert? Java Basics - Anfänger-Themen 3
J HashSet Fehlerhaft Java Basics - Anfänger-Themen 10
J HashSet Implementierung Java Basics - Anfänger-Themen 16
D Problem mit HashSet Java Basics - Anfänger-Themen 12
darekkay Datentypen HashSet bzw. LinkedList mit Werten initialisieren Java Basics - Anfänger-Themen 3
B Hashset iterieren problem Java Basics - Anfänger-Themen 3
C HashSet Problem Java Basics - Anfänger-Themen 3
DasBrot Datentypen HashSet contains() Java Basics - Anfänger-Themen 3
F HashSet u. LinkedHashSet Zugriff auf Werte? Java Basics - Anfänger-Themen 2
F HashSet und LinkedHashSet Instanzierung warum so? Java Basics - Anfänger-Themen 7
M HashSet.contains() Java Basics - Anfänger-Themen 2
N Map<String, HashSet<String>> Umwandeln in Map<String, ArrayList<String>> Java Basics - Anfänger-Themen 14
neurox Limit bei HashSet? Java Basics - Anfänger-Themen 2
Povlsen84 HashSet mit eigenen Datentypen Java Basics - Anfänger-Themen 6
G HashSet vs. TreeSet Java Basics - Anfänger-Themen 3
G hashset überschreibt werte bei add Java Basics - Anfänger-Themen 1
G Wie mach ich ein HashSet für eigene Objecte? Java Basics - Anfänger-Themen 9
M HashSet Initialisierungsgröße? Java Basics - Anfänger-Themen 5
F doppelte Elemente in HashSet Java Basics - Anfänger-Themen 5
G Probleme mit HashSet Java Basics - Anfänger-Themen 5
S HashSet in HashMap, Zugriff Java Basics - Anfänger-Themen 3
G Zahlen aus HashSet in ein int Array übergeben Java Basics - Anfänger-Themen 15
G Hashset verknüpfen mit BufferedReader Java Basics - Anfänger-Themen 18
L Was ist ein HashSet? Java Basics - Anfänger-Themen 33
G HashSet Java Basics - Anfänger-Themen 21
P HashSet und Referenzen Java Basics - Anfänger-Themen 9
B Warum hat HashSet kein get(Object o) ? Java Basics - Anfänger-Themen 8
H umwandeln zu Hashset ?! Java Basics - Anfänger-Themen 7
J Interface Comparable<T> Java Basics - Anfänger-Themen 10
L Interface & Comparable Java Basics - Anfänger-Themen 15
I Generics und Comparable Java Basics - Anfänger-Themen 14
O Comparable Generic Java Basics - Anfänger-Themen 24
R Quicksort mit Interface Comparable Java Basics - Anfänger-Themen 6
Kornblume Comparable Interface für Objektvergleiche nutzen Java Basics - Anfänger-Themen 15
C Was macht `public class ClassName<T extends Comparable<T>>`? Java Basics - Anfänger-Themen 14
N Comparable bzw Comparator Java Basics - Anfänger-Themen 5
M Generische Liste aus Comparable-Objekten Java Basics - Anfänger-Themen 6
R Interface Eigene Objekte in Listen sortieren mit Interface Comparable Java Basics - Anfänger-Themen 5
K Comparable - Objekte aus Array vergleichen und größtes auswählen Java Basics - Anfänger-Themen 1
Shizmo Frage zu Comparable Java Basics - Anfänger-Themen 4
L LinkedList Comparable < > MEHRFACH implementieren? Java Basics - Anfänger-Themen 3
N Datentypen LocalDate Generic Comparable Java Basics - Anfänger-Themen 2
S Generics und Comparable Interface Java Basics - Anfänger-Themen 5
N Compiler-Fehler Comparable / compareTo implementierung Java Basics - Anfänger-Themen 2
F Comparable mit String Java Basics - Anfänger-Themen 5
M Comparable und Comparator nicht ganz klar Java Basics - Anfänger-Themen 1
F Objekte sortieren mit Comparable Java Basics - Anfänger-Themen 9
R Mehrere Interfaces(Comparable, ...) Java Basics - Anfänger-Themen 2
B Comparable & Comparator Java Basics - Anfänger-Themen 9
C Comparable Interface Java Basics - Anfänger-Themen 8
T Interface Interface Comparable Problem... Java Basics - Anfänger-Themen 2
H Interface Comparable Verständnisfrage Java Basics - Anfänger-Themen 6
B Object "Method" in TreeSet, Fehler beim Vergleichen/Comparable Java Basics - Anfänger-Themen 9
pg1337 Interface Comparable-Interface bei HashMap Java Basics - Anfänger-Themen 21
J Probleme mit Comparable, compareTo() Java Basics - Anfänger-Themen 2
A Comparable interface Java Basics - Anfänger-Themen 26
I Interface Comparable für Server-Item-Interface Java Basics - Anfänger-Themen 12
P Comparable und Generics Java Basics - Anfänger-Themen 6
S comparable und equals Java Basics - Anfänger-Themen 7
S Unterschied Comparable und Comparator Java Basics - Anfänger-Themen 2
M Frage zum Interface Comparable Java Basics - Anfänger-Themen 3
S Comparable Java Basics - Anfänger-Themen 4
H Comparable und Comparator Java Basics - Anfänger-Themen 22
S instanceof Comparable...geht nicht? Java Basics - Anfänger-Themen 20
M comparable funktion & reverse funktion Java Basics - Anfänger-Themen 8
H Mehrere Comparable Java Basics - Anfänger-Themen 4
S Comparator / Comparable ? Java Basics - Anfänger-Themen 3
D Comparable - Bucketsort / Radixsort? Java Basics - Anfänger-Themen 2
B Mehrere Werte mit Comparable sortieren Java Basics - Anfänger-Themen 14
S String umwandeln in Comparable Java Basics - Anfänger-Themen 6
R Comparable Interface Funktionalität selbst programmieren? Java Basics - Anfänger-Themen 3
A Interface Comparable Java Basics - Anfänger-Themen 2
J Comparable Java Basics - Anfänger-Themen 9
D Frage zu Collection.sort bzw. Comparator u. Comparable Java Basics - Anfänger-Themen 2
B Wann Comparator und wann Comparable Java Basics - Anfänger-Themen 6
frau-u Wie vergleicht Comparable Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben