Dziejszy Java Killer prosty i niezbyt wyrafinowany. Ależ jak wiele bólu może dostarczyć, gdy taki kod dostanie się na produkcje, wie tylko programista, który to przeżył...
No dobra, nie jest, aż tak tragicznie, ale mimo wszystko boli. Pytanie na dziś, co wypisze na konsoli działanie poniższego programu:
public static void main(String[] args) {
SortedSetnames = new TreeSet ();
names.add("Gąskalska Anna");
names.add("Enigmatyczna Jola");
names.add("Ambroży Tomasz");
names.add("Ędward Ącki");
System.out.println(names);
}
Odpowiedzi możliwych kilka, a prawdziwa jak zwykle tylko jedna:
A) [Gąskalska Anna]
B) [Ambroży Tomasz, Enigmatyczna Jola, Gąskalska Anna, Ędward Ącki]
C) [Ambroży Tomasz, Enigmatyczna Jola, Ędward Ącki, Gąskalska Anna ]
D) [Ambroży Tomasz, Ędward Ącki, Enigmatyczna Jola, Gąskalska Anna ]
E) java.util.SortedSet@122cdb6
F) błąd kompilacji
Otóż okazuje się, że prawidłowa odpowiedź to:
B) [Ambroży Tomasz, Enigmatyczna Jola, Gąskalska Anna, Ędward Ącki]
Jak to!? Przecież miała być lista posortowana alfbatecznie! Co jest grane? Cóż, program zachowuje się zgodnie ze specyfikacją, gdzie wyraźnie czytamy:
Method comparesTo (...) compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. (...) Method compareTo returns the difference of the two character values at position k
in the two string -- that is, the value this.charAt(k)-anotherString.charAt(k).
A jak przyjrzymy się znakom Unicode, polskie krzaczki mają wartości o niebo większe od standardowych literek z alfabetu łacińskiego. I tak ę, ą, ć, ń, ż, ź, ś, ó oraz ł będzie zawsze stać za całą resztą abecadła.
Miejscie to prosze na uwadze, sortując swoje listy :)
13 komentarzy:
A co by było jakbyś napisał tak:
names.add(new String("Gąskalska Anna", "ISO-8859-2"));
names.add(new String("Enigmatyczna Jola", "ISO-8859-2"));
names.add(new String("Ambroży Tomasz", "ISO-8859-2"));
names.add(new String("Ędward Ącki", "ISO-8859-2"));
Odnoszę wrażenie, że mogłoby być OK.
String nie ma takiego konstruktora
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html
@michał mech: nota bene fajnie twoj blog sie zaczyna, tez bede sie przymierzal do seama ale czekam na wydanie oficjalnej ksiazki w lutym 2009
Zgadłem! Zgdałem! Ale chyba tylko dlatego, że przeczuwałem jakieś coś, co przeczy zdrowemu (polskiemu) rozsądkowi. Po przeczytaniu wyjaśnienia zrobiło się klarowniej. Dzięki!
@jacek: milo mi ze coraz czesciej zagladasz tutaj :)
Jak ja lubię ten problem. Zresztą jest to utrapienie wielu mniej doświadczonych programistów, którzy jeszcze nie spotkali się z "Nowym alfabetem Języka Polskiego". Najweselej jest jednak jak za sortowanie tego typu biorą się innostriency :)
@Michał Mech: tak to ta ksiazka, czekam na nia z niecierpliwoscia
pytanie czy jak w koncu Ędward Ącki wystartuje w wyborach, to czy bedzie dobrze posortowany na liście potencjalnych kandydatów ;)
Paweł książka ta jest już dostępna dzięki Safari Early Access: http://my.safaribooksonline.com/9780137151660
Też niecierpliwie na nią czekam. Z moich obecnych obserwacji jedną z leszych pozycji wydaje się być ... oficjalna dokumentacja :)
Co ciekawe:
SortedSet names = new TreeSet(Collator.getInstance(new Locale("pl_PL")));
names.add("Gąskalska Anna");
names.add("Enigmatyczna Jola");
names.add("Ambroży Tomasz");
names.add("Ędward Ącki");
System.out.println(names);
daje:
[Ambroży Tomasz, Ędward Ącki, Enigmatyczna Jola, Gąskalska Anna]
czyli też niezbyt ;-)
Akurat ten killer byl z tych prostych, żeby nie powiedziec ze byl najprostszy z dotychczasowo opublikowanych:)
new TreeSet(Collator.getInstance(new Locale("pl_PL")));
Byłoby miło gdyby to działało poprawnie... Jest jakaś możliwość zrobienia żeby było dobrze?
No to jeszcze prawidłowe rozwiązania, a raczej oczekiwane rozwiązanie - jak to napisać, by sortowanie uwzględniało lokale?
Nie wiem, to i chętnie się dowiem :)
Tomasz Bartczak
Racjonalny Developer
Jak pokazał Macieq zwykły Collator też nie działa poprawnie (mimo ze podobno "The Collator class performs locale-sensitive String comparison".
Najlepiej napisać chyba na szybko regułę do polskiego języka i wykorzystać RuleBasedCollator IMHO
http://java.sun.com/j2se/1.4.2/docs/api/java/text/RuleBasedCollator.html
Prześlij komentarz