Gdy musisz przejrzeć kolekcję i utworzyć ciąg danych oddzielonych separatorem, zawsze kończy się to dodatkowym separatorem na końcu, np.
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Daje coś w rodzaju: serverId_1, serverId_2, serverId_3,
Chciałbym usunąć ostatni znak w StringBuilder (bez konwersji, ponieważ nadal potrzebuję go po tej pętli).
java
stringbuilder
Mateusz
źródło
źródło
StringJoiner
: stackoverflow.com/a/29169233/901641Odpowiedzi:
Inni wskazali tę
deleteCharAt
metodę, ale oto inne alternatywne podejście:Alternatywnie skorzystaj z
Joiner
klasy z Guawy :)Począwszy od Java 8,
StringJoiner
jest częścią standardowego środowiska JRE.źródło
Joiner
też w ichStringUtils
. commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)Innym prostym rozwiązaniem jest:
Bardziej skomplikowane rozwiązanie:
Powyższe rozwiązanie zakłada, że
sb.length() > 0
... tzn. Istnieje „ostatni znak” do usunięcia. Jeśli nie możesz przyjąć tego założenia i / lub nie możesz poradzić sobie z wyjątkiem, który powstałby, gdyby założenie było niepoprawne, najpierw sprawdź długość StringBuilder; na przykładlub
źródło
źródło
sb.length() == 0
również niebezpieczneseparator.length()
zamiast 1.Od wersji Java 8 klasa String ma metodę statyczną
join
. Pierwszy argument to ciąg znaków, który chcesz między każdą parą ciągów, a drugi toIterable<CharSequence>
(które są obydwoma interfejsami, więc coś w rodzajuList<String>
działa. Więc możesz po prostu to zrobić:Również w Javie 8 możesz użyć nowej
StringJoiner
klasy do scenariuszy, w których chcesz zacząć konstruować ciąg, zanim będziesz mieć pełną listę elementów do umieszczenia w nim.źródło
String.join
zamiastStringJoiner
.Wystarczy uzyskać pozycję ostatniego wystąpienia postaci.
Ponieważ
lastIndexOf
przeprowadzi wyszukiwanie wsteczne i wiesz, że znajdzie się przy pierwszej próbie, wydajność nie będzie tutaj problemem.EDYTOWAĆ
Ponieważ ciągle podnoszę swoją odpowiedź (dzięki ludzie 😊), warto wziąć pod uwagę, że:
W Javie 8 i nowszej byłoby po prostu bardziej czytelne i wyraźne korzystanie z StringJoiner . Ma jedną metodę prostego separatora oraz przeciążenie prefiksu i sufiksu.
Przykłady zaczerpnięte stąd: przykład
Przykład użycia prostego separatora:
Wynik:
Przykład z przyrostkiem i przedrostkiem:
Wynik
źródło
,
ponieważ była to ostatnia wypowiedźfor loop
. ChodzilastInfexOf
o czytelność i sprawia, że jest to łatwe, jeśli nie chcesz pamiętać, czy jest indeksowane na 0, czy nie. Co więcej, nie musisz wtrącać się w długość łańcucha znaków. To tylko dla wygody.W tym przypadku,
jest preferowane, ponieważ po prostu przypisuje ostatnią wartość,
'\0'
podczas gdy usuwa ostatni znakSystem.arraycopy
źródło
setLength
Połączenie nie jest przypisywanie nic do ostatniej wartości. Bufory ciągów Java nie są zakończone zerem / zerem. W rzeczywistościsetLength
to po prostu aktualizacjalength
pola.arraycopy
kopiuje 0 elementów, więc myślę, że można go zoptymalizować.Za
Java-8
pomocą statycznej metodyString
klasyString#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)
.WYNIK
źródło
Kolejna alternatywa
źródło
Alternatywnie,
źródło
źródło
Jeszcze jedna alternatywa:
źródło
Aby uniknąć
prefix
ponownego uruchomienia (wpłynąć na wydajność) użycia TextUtils.isEmpty:źródło
Możesz spróbować użyć klasy „Joiner” zamiast usuwać ostatni znak z wygenerowanego tekstu;
źródło
Robię coś takiego:
źródło
Oto inne rozwiązanie:
źródło
Osobiście lubię dodawać znak backspace (lub więcej dla dłuższego „separatora”) na końcu:
Pamiętaj, że ma problemy:
\b
wyświetlania zależy od środowiska,length()
oString
treści może być różna od długości znaków „widoczny”Kiedy
\b
wygląda OK, a długość nie ma znaczenia, np. Logowanie do konsoli, wydaje mi się to wystarczająco dobre.źródło
stringBuilder.Remove (stringBuilder.Length - 1, 1);
źródło