2011-06-02 13 views
7

Zastanawiam się, dlaczego parametr indexOf metody int, gdy opis mówi char.Dlaczego parametr string.indexOf jest int w Java

public int indexOf (int ch)

Returns the index within this string of the first occurrence of the specified **character** 

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#indexOf%28int%29

Also, both of these compiles fine: 
char c = 'p'; 
str.indexOf(2147483647); 
str.indexOf(c); 

a] Zasadniczo, co jestem zagubiony int w Java jest 32-bitowy, a znaki Unicode są 16 bity.

b] Dlaczego nie używać znaku zamiast używać int. Czy to jest jakaś optymalizacja wydajności? Czy znaki są trudne do przedstawienia niż int? W jaki sposób ?

Zakładam, że powinno to być proste rozumowanie i to jeszcze bardziej informuje mnie o tym!

Dzięki!

Odpowiedz

12

Przyczyną jest to, że oczekuje punktu kodowego Unicode, a nie 16-bitowego znaku "UTF-16". Punkty kodu Unicode mają długość do 21 bitów.

(UTF-16 reprezentacja dłuższy punkt kodowy jest rzeczywiście 2 wartości "charakter" 16-bitowe wartości te są znane jako początkowe i końcowe zastępczą;. D800 do DBFF i DC00 do DFFF odpowiednio; patrz Unicode FAQ - UTF-8, UTF-16, UTF-32 & BOM dla krwawych szczegółów)

Jeśli dasz indexOf(int) kod Point> 65535 będzie poszukać pary z UTF-16 znaków, które kodują kodowy..

Jest to określone przez javadoc (choć nie bardzo wyraźnie), a badanie kodu wskazuje, że jest to rzeczywiście jak metoda jest stosowana.


Dlaczego nie wystarczy użyć 16-bitowych znaków?

To dość oczywiste. Gdyby to zrobili, nie byłoby łatwego sposobu na zlokalizowanie punktów kodu większych niż 65535 w łańcuchach. Byłoby to dużym utrudnieniem dla osób, które rozwijają umiędzynarodowione aplikacje, w których tekst może zawierać takie punkty kodowe. (Wiele rzekomo umiędzynarodowionych aplikacji składa się na błędne założenie, że char reprezentuje punkt kodowania, często nie ma to znaczenia, ale czasami tak się dzieje.)

Ale nie powinno to mieć dla ciebie żadnego znaczenia. Metoda będzie działać, jeśli ciągi zawierają tylko 16-bitowe kody ... lub, o ile to możliwe, tylko kody ASCII.

+0

Thnx za odpowiedź. ok, więc teraz widzę indexOf (int) oczekuje codepoint Unicode, moje inne pytanie było .. dlaczego to jest? . Dlaczego po prostu nie używać 16-bitowych znaków? – codeObserver

+1

Ponieważ charecter w unicode ma naprawdę 22 bity, a nie 16. Istnieją "znaki/litery" (punkty kodowe), których nie można zapisać w charcie java. Z tego powodu łańcuch Java może wykorzystywać 2 znaki do przechowywania jednego "codepoint/letter" (zob. Parami zastępcze utf-16, jeśli naprawdę chcesz wiedzieć). – MTilsted

3

Znaki w języku Java są przechowywane w ich reprezentacji liczb całkowitych Unicode. Dokumentacja klasy Character zawiera więcej szczegółów na temat tego formatu.

Od docs na tej stronie:

Metody, które akceptują nośniku int Wartość wszystkich znaków Unicode, w tym znaków uzupełniających. Na przykład Character.isLetter (0x2F81A) zwraca true, ponieważ wartość code point reprezentuje literę (ideogram CJK).

+0

Thnx. 2 oświadczenia doc: Dolny (najmniej znaczące) 21 bitów int są używane do reprezentowania Unicode punktów kodowych i górną (11) najbardziej znaczących bitów musi być zero. specyfikacja Unicode, który zdefiniowano jako podmioty znaków o stałej szerokości 16-bitowych Więc jeśli Unicode to 16 bitów, dlaczego użyciu 21 bitów do ich reprezentowania? – codeObserver

+0

Tak, ale ciągi są bajtowe [] pod okładkami zakodowanymi jako UTF-8. Znaki standardowe (0-255) zajmują tylko jeden bajt (nie dwa bajty, które zajmowałby pełnowymiarowy znak). Znaki powyżej 255 zajmują wiele bajtów, czasem więcej niż 2 bajty. Zakodowany znak ma liczbę całkowitą (32-bitową) - to jest to, co indeksOff() wyszukuje – Bohemian

+0

@ p1 Unicode nie był 16-bitowy przez bardzo długi czas. Unicode 2.0 usunął ograniczenie 16-bitowe i to było FIFTEEN lat temu (czuję się stary). Technicznie ISO-10646 jest 31-bitową przestrzenią adresową, a Unicode może w teorii reprezentować dowolną z nich. W rzeczywistości UTF-16 jest ograniczony do 21 bitów, a Unicode skutecznie zobowiązał się do obsługi tylko tych 21 bitów. Jest bardzo mało prawdopodobne, że ISO-10646 kiedykolwiek będzie mógł zsynchronizować się z Unicode w sposób, który złamie kodowanie UTF-16, więc 21-bitowy jest obecnie sztywnym limitem. – Cowan

0

Metoda str.indexOf(int) przyjmuje int. Jeśli podasz w nim kod char, java rzuci char na int, ponieważ char jest liczbą 16-bitową.

+0

tak, ale int to 32 bity w java i to wprowadza mnie w błąd! – codeObserver

+1

@ p1, współrzędne kodowe są 32-bitowe i właśnie tego szuka. –

0

Java wykonuje całą masę niejawnych reguł typowania, które są wykonywane pod maską. W przypadku prymitywów istnieją specjalne zasady, które są opisane w dokumencie Conversions and Promotions, będącym częścią dokumentacji Java firmy Sun. W przypadku konkretnego pytania konwersja int na znak jest "zawężeniem prymitywnego nawrócenia". Patrz sekcja 5.1.3 w powyższym dokumencie.

Powszechnie stosowaną praktyką programistyczną jest zamiana małych liczb całkowitych pozytywnych i znaków zakodowanych jako liczby całkowite. To sięga do ich nierozróżnialnego użycia w C, kiedy ASCII było wszystkim, co istniało.

Powiązane problemy