W jaki sposób można sortować obiekty zgodnie z ustawieniami narodowymi?
W jaki sposób można sortować obiekty zgodnie z ustawieniami narodowymi?
Zacznijmy od przykładu. Załóżmy, że obiektami, które trzeba uporządkować są obiekty klasy Osoba:
public class Osoba { private String imie; private String nazwisko; public Osoba(String imie, String nazwisko) { this.imie = imie; this.nazwisko = nazwisko; } public String getImie() { return imie; } public String getNazwisko() { return nazwisko; } @Override public String toString() { return imie + " " + nazwisko; } }
Do przetestowania sortowania użyjemy klasy:
public class Sortowanie { public static void main(String[] args) { List<Osoba> lista = new ArrayList<>(); lista.add(new Osoba("Marek", "Kowalski")); lista.add(new Osoba("Łukasz", "Kowalski")); lista.add(new Osoba("Adam", "Świderski")); lista.add(new Osoba("Agata", "Sowińska")); lista.add(new Osoba("Anna", "Łęczycka")); lista.add(new Osoba("Stefan", "Żurek")); lista.add(new Osoba("Jerzy", "Zabłocki")); ... } }
Jako kryterium uporządkowania przyjmiemy nazwisko, a jeśli wybór nie będzie rozstrzygnięty, to w drugiej kolejności imię.
Można do tego wykorzystać odpowiednio zdefiniowany komparator:
Collections.sort(lista, new Comparator<Osoba>() { @Override public int compare(Osoba o1, Osoba o2) { int porzadek = o1.getNazwisko().compareTo(o2.getNazwisko()); if (porzadek != 0) { return porzadek; } return o1.getImie().compareTo(o2.getImie()); } }); System.out.println(lista);
Jednakże, wynik sortowania jest daleki od tego czego oczekujemy:
[Marek Kowalski, Łukasz Kowalski, Agata Sowińska, Jerzy Zabłocki, Anna Łęczycka, Adam Świderski, Stefan Żurek]
Aby sortowanie było czułe na znaki narodowe należy użyć klasy java.text.Collator. Pełni ona rolę komparatora, ale "zna" lokalizację.
Sortowanie należy zrealizować następująco:
Collections.sort(lista, new Comparator<Osoba>() { @Override public int compare(Osoba o1, Osoba o2) { Collator c = Collator.getInstance(new Locale("pl")); c.setStrength(Collator.PRIMARY); int porzadek = c.compare(o1.getNazwisko(), o2.getNazwisko()); if (porzadek != 0) { return porzadek; } return c.compare(o1.getImie(), o2.getImie()); } }); System.out.println(lista);
Wówczas wynik jest taki, jakiego oczekujemy:
[Łukasz Kowalski, Marek Kowalski, Anna Łęczycka, Agata Sowińska, Adam Świderski, Jerzy Zabłocki, Stefan Żurek]
Metoda setStrength służy do określenia, kiedy znaki mają być rozróżniane, tzn. np.: czy pary liter 'a' i 'ą' mają być traktowane jednakowo, czy istotna jest wielkość liter itd.