Egen ordning i trädstrukturerade samlingar
Skicka in en Comparator till TreeMap/TreeSet för att definiera domänspecifika sorteringsordningar.
Egen ordning i trädstrukturerade samlingar är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.
Varför anpassad ordning?
Trädliknande samlingar (TreeMap, TreeSet) använder som standard naturlig ordning. När domänobjekten saknar en naturlig ordning, eller när Ni behöver en annan sortering, anger Ni en Comparator när samlingen skapas.
Comparator när TreeMap skapas
Skicka med en comparator för att sortera nycklar enligt en anpassad regel – till exempel i omvänd alfabetisk ordning:
import java.util.*;
TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
map.put("banana", 2);
map.put("apple", 1);
map.put("cherry", 3);
map.forEach((k,v) -> System.out.println(k)); // cherry, banana, appleComparator när TreeSet skapas
Ange en comparator till TreeSet för att styra sorteringsordningen oberoende av elementens naturliga ordning:
TreeSet<String> byLength = new TreeSet<>(
Comparator.comparingInt(String::length)
.thenComparing(Comparator.naturalOrder())
);
byLength.addAll(List.of("fig","apple","kiwi","date","banana"));
for (String s : byLength) System.out.print(s + " ");
// fig date kiwi apple bananaSortera objekt efter flera fält
Kedja comparators för att sortera efter ett primärt fält och sedan efter ett sekundärt fält som skiljer lika värden åt:
record Employee(String name, String dept, int salary) {}
TreeSet<Employee> sorted = new TreeSet<>(
Comparator.comparing(Employee::dept)
.thenComparingInt(Employee::salary).reversed()
.thenComparing(Employee::name)
);
sorted.add(new Employee("Alice", "Eng", 90_000));
sorted.add(new Employee("Bob", "Eng", 85_000));
sorted.add(new Employee("Carol", "HR", 70_000));
for (Employee e : sorted) System.out.println(e.dept()+" "+e.name());Överensstämmelse med equals
Kritisk regel: den comparator som används av TreeSet/TreeMap definierar likhet för samlingen. Om comparator.compare(a, b) == 0 betraktas både a och b som samma nyckel – även om a.equals(b) är false.
// Comparator ignoring case — "apple" and "APPLE" become the same key!
TreeSet<String> ci = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
ci.add("apple");
ci.add("APPLE"); // not added — same by comparator
System.out.println(ci.size()); // 1Skiftlägesokänslig TreeMap
Ett vanligt praktiskt behov är en TreeMap där nycklarna är skiftlägesokänsliga strängar, vilket är användbart för HTTP-huvuden och konfigurationsnycklar:
TreeMap<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
headers.put("Content-Type", "application/json");
headers.put("content-type", "text/html"); // overwrites!
System.out.println(headers.get("CONTENT-TYPE")); // text/html
System.out.println(headers.size()); // 1Nullsäker comparator
Trädliknande samlingar med naturlig ordning kastar NPE för null-nycklar. Använd en nullsäker comparator för att tillåta null som den minsta nyckeln:
TreeMap<String, Integer> map = new TreeMap<>(
Comparator.nullsFirst(Comparator.naturalOrder())
);
map.put(null, 0);
map.put("b", 2);
map.put("a", 1);
map.forEach((k,v) -> System.out.println(k + "=" + v));
// null=0, a=1, b=2Exempel på domänobjekt: produkt efter pris
Sortera produkter efter pris i en TreeSet och använd namnet som skiljande faktor för att bevara unika element:
record Product(String name, double price) {}
TreeSet<Product> catalog = new TreeSet<>(
Comparator.comparingDouble(Product::price)
.thenComparing(Product::name)
);
catalog.add(new Product("Widget", 9.99));
catalog.add(new Product("Gadget", 24.99));
catalog.add(new Product("Donut", 9.99));
catalog.forEach(p -> System.out.println(p.name() + " $" + p.price()));
// Donut $9.99, Widget $9.99, Gadget $24.99Hämta comparatorn
Anropa comparator() på en TreeMap/TreeSet för att hämta den anpassade comparatorn. Returnerar null om naturlig ordning används.
TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
System.out.println(map.comparator() != null); // true
TreeMap<String, Integer> natural = new TreeMap<>();
System.out.println(natural.comparator()); // nullSammansättning av comparators
Javas Comparator erbjuder kedjbara fabriksmetoder för en tydlig sammansättning:
Comparator<String> comp =
Comparator.comparingInt(String::length) // by length
.thenComparing(Comparator.naturalOrder()); // then alphabetically
TreeSet<String> ts = new TreeSet<>(comp);
ts.addAll(List.of("go", "java", "c", "rust", "py"));
ts.forEach(s -> System.out.print(s + " "));
// c go py java rustNär Ni INTE bör använda en anpassad comparator
Undvik att använda en comparator som inte överensstämmer med equals för TreeMap-nycklar eller TreeSet-element – det leder till förvirrande poster som verkar saknas. Säkerställ att compare(a, b) == 0 gäller om och endast om a.equals(b) gäller, så att samlingen fungerar korrekt i alla sammanhang.
Snabb kontroll
En TreeSet använder endast en comparator baserad på String::length. Vad händer när Ni lägger till både "cat" och "dog"?
Sammanfattning: Anpassad ordning
Viktiga punkter:
- Skicka en Comparator till TreeMap- eller TreeSet-konstruktorn för att definiera en anpassad ordning
- Jämlikhet enligt Comparator styr unikheten i träd-baserade samlingar
- Se till att Comparator är konsekvent med equals för att undvika överraskningar
- Använd Comparator.nullsFirst/nullsLast för null-säker sortering
- Kedja med thenComparing för sortering på flera fält
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 104
- Lektioner
- 374
Vanliga frågor
Är lektionen ”Egen ordning i trädstrukturerade samlingar” gratis?
Ja – hela texten till ”Egen ordning i trädstrukturerade samlingar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Egen ordning i trädstrukturerade samlingar”?
Skicka in en Comparator till TreeMap/TreeSet för att definiera domänspecifika sorteringsordningar. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Java Academy?
Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Egen ordning i trädstrukturerade samlingar”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Java Academy-lektionen?
Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- TreeMap: sorterade nyckel-värde-par
- Delkartor och intervallvyer
- TreeSet och NavigableSet
- Egen ordning i trädstrukturerade samlingar