Sortering i Java
Formål: lære at sortere objekter i Java
Vi bruger alene:
Comparable<T>implementeret i selve domæneklassen- Navngivne
Comparator<T>-klasser
Brug Comparable, når objektet har én naturlig sortering (fx film efter titel).
public class Movie implements Comparable<Movie> {
private final String title;
private final int year;
public Movie(String title, int year) {
this.title = title;
this.year = year;
}
public String getTitle() { return title; }
public int getYear() { return year; }
// Naturlig sortering: alfabetisk efter titel
@Override
public int compareTo(Movie other) {
return this.title.compareTo(other.title);
}
@Override
public String toString() {
return title + " (" + year + ")";
}
}
Sortering med naturlig orden:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DemoComparable {
public static void main(String[] args) {
List<Movie> movies = new ArrayList<>();
movies.add(new Movie("Titanic", 1997));
movies.add(new Movie("Avatar", 2009));
movies.add(new Movie("Inception", 2010));
Collections.sort(movies); // bruger Movie.compareTo(...)
System.out.println(movies);
}
}
Brug Comparator, når du vil kunne sortere på flere forskellige måder, eller når du ikke kan/skal ændre domæneklassen.
import java.util.Comparator;
public class MovieYearAscendingComparator implements Comparator<Movie> {
@Override
public int compare(Movie m1, Movie m2) {
// Brug Integer.compare for korrekt håndtering af lighed
return Integer.compare(m1.getYear(), m2.getYear());
}
}
Brug:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DemoYearAscending {
public static void main(String[] args) {
List<Movie> movies = new ArrayList<>();
movies.add(new Movie("Titanic", 1997));
movies.add(new Movie("Avatar", 2009));
movies.add(new Movie("Inception", 2010));
Collections.sort(movies, new MovieYearAscendingComparator());
System.out.println(movies);
}
}
import java.util.Comparator;
public class MovieYearDescendingComparator implements Comparator<Movie> {
@Override
public int compare(Movie m1, Movie m2) {
// Vend rækkefølgen
return Integer.compare(m2.getYear(), m1.getYear());
}
}
Når to film har samme år, sortér alfabetisk efter titel.
(Uden thenComparing laver vi det selv.)
import java.util.Comparator;
public class MovieYearThenTitleComparator implements Comparator<Movie> {
@Override
public int compare(Movie m1, Movie m2) {
int yearCompare = Integer.compare(m1.getYear(), m2.getYear());
if (yearCompare != 0) {
return yearCompare;
}
// Sekundær: titel
return m1.getTitle().compareTo(m2.getTitle());
}
}
Brug:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DemoYearThenTitle {
public static void main(String[] args) {
List<Movie> movies = new ArrayList<>();
movies.add(new Movie("Zodiac", 2007));
movies.add(new Movie("No Country for Old Men", 2007));
movies.add(new Movie("Arrival", 2016));
movies.add(new Movie("Avatar", 2009));
Collections.sort(movies, new MovieYearThenTitleComparator());
System.out.println(movies);
}
}
| Problem | Løsning | Fordel |
|---|---|---|
| En naturlig, standardiseret orden | Implementér Comparable i klassen | Gør Collections.sort(list) simpelt |
| Flere alternative sorteringer | Lav navngivne Comparator-klasser | Genbrugelige, testbare sorteringsregler |
| Sekundære nøgler (tie-breakers) | Håndtér i compare(...) | Fuld kontrol, ingen lambdas |
Person: Lav en
Person-klasse (name,age).- Implementér
Comparable<Person>med naturlig orden eftername.
- Implementér
Alder-Comparator: Lav
PersonAgeAscendingComparatorogPersonAgeDescendingComparator.Kombineret: Lav
PersonAgeThenNameComparator, der sorterer efter alder og derefter navn.Testprogram: Opret en liste af
Person-objekter og vis udskrifter for alle tre sorteringer.
- Returnér negativt/0/positivt konsekvent
- Brug
Integer.compare(a, b)i stedet fora - b - Sørg for at
compare(a, b) == 0når objekter betragtes som lige i den valgte orden - Undgå
NullPointerException(afklar politik fornull, eller forbydnull)
Comparable= naturlig orden i klassen selvComparator= navngivne strategier for alternative sorteringer- Ingen brug af lambda/anonyme klasser → alt ligger i tydelige, genbrugelige klasser