2009-05-19 13 views
7

Nie rozumiem, dlaczego Java [String.substring() metoda] (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#substring(int,%20int%29) jest określony tak, jak jest.Nie mogę powiedzieć, aby zacząć od pozycji numerowanej i zwrócić określoną liczbę znaków, muszę obliczyć I jeśli określę pozycję końcową poza końcem String, zamiast tylko zwrócić resztę String dla mnie, Java zgłasza wyjątekJak działa ciąg substring()?

Jestem przyzwyczajony do języków, w których podciągu() (lub substr()) przyjmuje dwa parametry: pozycję początkową i długość.Czy to jest obiektywnie lepsze niż sposób, w jaki robi to Java, a jeśli tak, to czy możesz to udowodnić? Jaka jest najlepsza specyfikacja języka dla substring(), którą masz widzisz, a kiedy jest to dobry pomysł, aby język robił różne rzeczy? Czy to wyjątek IndexOutOfBoundsException, że Java rzuca dobry pomysł na projekt, czy nie? Czy to wszystko sprowadza się do osobistych preferencji?

+2

to rzeczywiście kwestia osobistych preferencji, co czyni ten "Subiektywny i argumentujący". Potrzebuję zarówno "długości", jak i "pozycji końcowej" smaków podłoży w różnym czasie, więc dla mnie nie ma sensu mówić, że jeden jest "lepszy" od drugiego. –

+2

Nie ma potrzeby dyskusji na ten temat tylko dlatego, że jest subiektywny. Do licha. Czy nie możemy rozmawiać o względnych zaletach decyzji językowych bez świętej wojny? Jeśli Jon Skeet uważa, że ​​warto na nie odpowiedzieć i nie jest tylko wezwaniem do kłótni, z pewnością to coś znaczy? – skiphoppy

+1

Jeśli zmienię go tak, by usunął słowa "zdziwienie" i "niedogodności", czy będzie mniej sprzeczny, skoro nikt się nie spiera? Czy pytania dotyczące projektowania języka (które w większości przypadków wiążą się z subiektywnym kompromisem) są nieodpowiednie dla Stack Overflow? – skiphoppy

Odpowiedz

1

Jeśli przejdziesz leave off the 2nd parameter, przejdziesz do końca łańcucha bez konieczności jego obliczania.

+0

Czasami chcesz od x do 20 znaków później lub na koniec ciągu, w zależności od tego, który z tych okresów jest krótszy. – Yishai

+1

Czasami potrzebujesz od x do połowy reszty ciągu, z wyłączeniem cyfr. Żaden interfejs API nie może spełnić wszystkich możliwych wymagań. –

+1

Żaden interfejs API nie spełnia wszystkich możliwych wymagań, ale uważam, że niektóre interfejsy API mogą w sposób oczywisty spełniać więcej wymagań niż inne. Nadal się nad tym zastanawiam i obserwuję odpowiedzi. :) – skiphoppy

3

Drugi parametr powinien być opcjonalny, pierwszy parametr powinien przyjmować wartości ujemne ..

5

jestem przyzwyczajony do języków gdzie podciąg() (lub substr()) bierze dwa parametry: pozycji startowej, i długość . Czy jest to obiektywnie lepsze niż sposób, w jaki robi to Java, a jeśli tak, to czy możesz to udowodnić?

Nie, nie jest obiektywnie lepszy. Wszystko zależy od kontekstu, w którym chcesz go użyć. Jeśli chcesz wyodrębnić podłańcuch o określonej długości, jest on zły, ale jeśli chcesz wyodrębnić podciąg kończący się na, powiedzmy, pierwsze wystąpienie "." w ciągu znaków jest to lepsze, niż gdybyś najpierw musiał obliczyć długość. Pytanie brzmi: które wymaganie jest bardziej powszechne? Powiedziałbym to drugie. Oczywiście najlepszym rozwiązaniem byłoby posiadanie obu wersji w API, ale jeśli potrzebujesz cały czas na podstawie długości, użycie statycznej metody użytkowej nie jest takie straszne.

Co do wyjątku, tak, to zdecydowanie dobry projekt. Poprosiłeś o coś konkretnego, a kiedy nie możesz uzyskać tej konkretnej rzeczy, interfejs API nie powinien próbować odgadnąć, co chciałbyś zamiast tego - w ten sposób błędy stają się widoczne szybciej.

Co więcej, Java DOES ma metodę alternative substring(), która zwraca podciąg od indeksu początkowego aż do końca łańcucha.

9

Są chwile, kiedy drugi parametr jest długością jest wygodniejszy, i są chwile, kiedy drugi parametr będący "przesunięciem do zatrzymania przed" jest wygodniejszy. Podobnie zdarzają się sytuacje, w których "jeśli daję ci coś, co jest zbyt duże, po prostu idę na koniec ciągu", jest to wygodne i czasami zdarza się, że wskazuje błąd i naprawdę powinien rzucić wyjątek.

Drugi parametr długości jest przydatny, jeśli masz stałą długość pola.Na przykład:

// C# 
String guid = fullString.Substring(offset, 36); 

Drugim parametrem jest przesunięcie jest przydatna, gdy idziesz do innego rozdzielany:

// Java 
int nextColon = fullString.indexOf(':', start); 
if (start == -1) 
{ 
    // Handle error 
} 
else 
{ 
    String value = fullString.substring(start, nextColon); 
} 

Zazwyczaj jeden chcesz użyć jest przeciwny do tego, który znajduje się na mojej obecnej platformie, z mojego doświadczenia :)

+4

+1 za to ostatnie zdanie. :) – jmucchiello

+0

+1, z tego samego powodu. –

+0

+1. Ten sam powód. –

1

Po uzyskaniu informacji zwrotnej, widzę, kiedy scenariusz z drugim parametrem jako indeksem jest przydatny, ale jak dotąd wszystkie te scenariusze wydają się działać w innym języku/Ograniczenia interfejsu API. Na przykład API nie zapewnia wygodnej procedury, która da mi ciągi przed i po pierwszym dwukropku w wejściowym łańcuchu znaków, więc zamiast tego otrzymam indeks String i podłańcuch wywołania(). (I to wyjaśnia, dlaczego parametr drugiej pozycji w substr() przekracza oczekiwany indeks o 1, IMO.)

Wydaje mi się, że przy bardziej wszechstronnym zestawie funkcji przetwarzania ciągów w pakiecie językowym, drugi scenariusz parametr-jako-indeks traci do drugiego parametru-jako-długości. Ale proszę, wyślijcie mi kontrprzykład. :)

+0

"Na przykład interfejs API nie zapewnia wygodnej procedury dostarczania łańcuchów przed i po pierwszym dwukropku w wejściowym łańcuchu znaków, więc zamiast tego uzyskuję indeks String i podłańcuch wywołania()." - Jeśli chciałbyś, aby API wszystko robił, mielibyśmy ogromne API do nauki, a Stack Overflow zawierałby odpowiedzi na pytanie, dlaczego ktoś nie użył jednej z 30000 metod w obiekcie String zamiast spędzić 30 sekund na samodzielnym pisaniu. Właśnie dlatego jesteśmy programistami, ponieważ nie wszystko zostało jeszcze napisane. Jeśli chcesz wykonać zadanie X dużo, napisz własną bibliotekę, aby to zrobić. –

+0

Dlaczego na świecie każdy chciałby napisać własną bibliotekę, skoro mieliby jedną implementację do debugowania wszystkich związanych z nią błędów ogrodzenia? – skiphoppy

0

Jeśli przechowujesz to daleko, problem powinien przestać dręczące swoje marzenia i będziesz w końcu osiągnąć dobry sen odpoczynek:

public String skipsSubstring(String s, int index, int length) { 
    return s.subString(index, index+length); 
} 
+0

Po prostu wysadzi w powietrze wyjątek IndexOutOfBoundsException. :) Musiałbym dodać sprawdzenie, aby drugi parametr do substring() był min (index + length, s.length()). – skiphoppy

+0

Po przeanalizowaniu implementacji String wydaje się, że Java nie będzie zbyt trudna, aby zapewnić oba paradygmaty: substring() może kontynuować tak, jak jest, a substr() może podążać za semantyką bardziej powszechną w innych językach. Wewnętrznie wdrożenie wydaje się być proste. – skiphoppy

+1

Myślę, że byłoby okropnie mieć zarówno substring(), jak i substr(), z inną semantyką.Mogę zagwarantować, że użyłbym niewłaściwego ponad połowę czasu - i myślę, że większość moich programistów też by to zrobiła. –