Als je een verzameling moet doorlopen en een reeks moet maken van elke gegevens, gescheiden door een scheidingsteken, krijg je altijd een extra scheidingsteken aan het einde, bijvoorbeeld
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Geeft zoiets als: serverId_1, serverId_2, serverId_3,
Ik wil het laatste teken in de StringBuilder verwijderen (zonder het te converteren omdat ik het na deze lus nog steeds nodig heb).
Antwoord 1, autoriteit 100%
Anderen hebben gewezen op de deleteCharAt
-methode, maar hier is nog een alternatieve benadering:
String prefix = "";
for (String serverId : serverIds) {
sb.append(prefix);
prefix = ",";
sb.append(serverId);
}
U kunt ook de Joiner
les van Guava🙂
Vanaf Java 8, StringJoiner
maakt deel uit van de standaard JRE.
Antwoord 2, autoriteit 70%
Een andere eenvoudige oplossing is:
sb.setLength(sb.length() - 1);
Een ingewikkelder oplossing:
De bovenstaande oplossing gaat ervan uit dat sb.length() > 0
… d.w.z. er is een “laatste teken” om te verwijderen. Als je die veronderstelling niet kunt maken, en/of je niet kunt omgaan met de uitzondering die zou ontstaan als de veronderstelling onjuist is, controleer dan eerst de lengte van de StringBuilder; bijv.
// Readable version
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
of
// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));
Antwoord 3, autoriteit 29%
if(sb.length() > 0){
sb.deleteCharAt(sb.length() - 1);
}
Antwoord 4, autoriteit 9%
Vanaf Java 8 heeft de klasse String een statische methode join
. Het eerste argument is een string die je tussen elk paar strings wilt hebben, en het tweede is een Iterable<CharSequence>
(die beide interfaces zijn, dus zoiets als List<String>
werkt. Dus je kunt dit gewoon doen:
String.join(",", serverIds);
Ook in Java 8 kunt u de nieuwe StringJoiner
klasse, voor scenario’s waarin je wilt beginnen met het construeren van de string voordat je de volledige lijst met elementen hebt om erin te plaatsen.
Antwoord 5, autoriteit 7%
Krijg gewoon de positie van het laatste teken dat voorkomt.
for(String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));
Aangezien lastIndexOf
een omgekeerde zoekopdracht uitvoert, en u weet dat het bij de eerste poging zal vinden, zal de prestatie hier geen probleem zijn.
BEWERKEN
Omdat ik steeds weer ophef over mijn antwoord (bedankt mensen 😊), is het de moeite waard hierover:
Vanaf Java 8en later zou het alleen maar beter leesbaar en explicieter zijn om StringJoiner.
Het heeft één methode voor een eenvoudig scheidingsteken en een overbelasting voor voor- en achtervoegsel.
Voorbeelden van hier: voorbeeld
Voorbeeld met eenvoudig scheidingsteken:
StringJoiner mystring = new StringJoiner("-"); // Joining multiple strings by using add() method mystring.add("Logan"); mystring.add("Magneto"); mystring.add("Rogue"); mystring.add("Storm"); System.out.println(mystring);
Uitvoer:
Logan-Magneto-Rogue-Storm
Voorbeeld met achtervoegsel en voorvoegsel:
StringJoiner mystring = new StringJoiner(",", "(", ")"); // Joining multiple strings by using add() method mystring.add("Negan"); mystring.add("Rick"); mystring.add("Maggie"); mystring.add("Daryl"); System.out.println(mystring);
Uitvoer
(Negan,Rick,Maggie,Daryl)
Antwoord 6, autoriteit 5%
In dit geval,
sb.setLength(sb.length() - 1);
heeft de voorkeur omdat het alleen de laatste waarde toewijst aan '\0'
terwijl het verwijderen van het laatste teken System.arraycopy
doet
Antwoord 7, autoriteit 2%
Met Java-8
kunt u de statische methode van de klasse String
gebruiken,
String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)
.
public class Test {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("James");
names.add("Harry");
names.add("Roy");
System.out.println(String.join(",", names));
}
}
UITVOER
James,Harry,Roy
Antwoord 8
Een ander alternatief
for(String serverId : serverIds) {
sb.append(",");
sb.append(serverId);
}
sb.deleteCharAt(0);
Antwoord 9
Als alternatief,
StringBuilder result = new StringBuilder();
for(String string : collection) {
result.append(string);
result.append(',');
}
return result.substring(0, result.length() - 1) ;
Antwoord 10
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true
Antwoord 11
Nog een alternatief:
public String join(Collection<String> collection, String seperator) {
if (collection.isEmpty()) return "";
Iterator<String> iter = collection.iterator();
StringBuilder sb = new StringBuilder(iter.next());
while (iter.hasNext()) {
sb.append(seperator);
sb.append(iter.next());
}
return sb.toString();
}
Antwoord 12
Gebruik TextUtils.isEmpty:
om het opnieuw invoeren (van invloed op de prestaties) van prefix
te voorkomen
String prefix = "";
for (String item : list) {
sb.append(prefix);
if (TextUtils.isEmpty(prefix))
prefix = ",";
sb.append(item);
}
Antwoord 13
U kunt proberen de ‘Joiner’-klasse te gebruiken in plaats van het laatste teken uit uw gegenereerde tekst te verwijderen;
List<String> textList = new ArrayList<>();
textList.add("text1");
textList.add("text2");
textList.add("text3");
Joiner joiner = Joiner.on(",").useForNull("null");
String output = joiner.join(textList);
//output : "text1,text2,text3"
Antwoord 14
Ik doe zoiets als hieronder:
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < value.length; i++) {
stringBuilder.append(values[i]);
if (value.length-1) {
stringBuilder.append(", ");
}
}
Antwoord 15
Hier is een andere oplossing:
for(String serverId : serverIds) {
sb.append(",");
sb.append(serverId);
}
String resultingString = "";
if ( sb.length() > 1 ) {
resultingString = sb.substring(1);
}
Antwoord 16
stringBuilder.Remove(stringBuilder.Length – 1, 1);
Antwoord 17
Ik merkte dat ik dit nogal vaak deed, dus schreef ik een benchmark voor de 3 belangrijkste technieken voor het toevoegen van scheidingstekens:
(benchmark met de juiste warming-up en 100 ronden van 100.000 iteraties)
“Toevoegen na”
static void appendAfter()
{
sb.append('{');
for (int i = 0; i < 10; i++)
{
sb.append('"');
sb.append(i);
sb.append('"');
sb.append(':');
sb.append(i);
sb.append(',');
}
sb.setLength(sb.length() - 1);
sb.append('}');
}
“Vooraf toevoegen”
static void appendBefore()
{
sb.append('{');
String delimiter = "";
for (int i = 0; i < 10; i++)
{
sb.append(delimiter);
sb.append('"');
sb.append(i);
sb.append('"');
sb.append(':');
sb.append(i);
delimiter = ",";
}
sb.append('}');
}
‘Misschien toevoegen’
static void appendMaybe()
{
sb.append('{');
for (int i = 0; i < 10; i++)
{
sb.append('"');
sb.append(i);
sb.append('"');
sb.append(':');
sb.append(i);
if (i < 9)
{
sb.append(',');
}
}
sb.append('}');
}
Ik heb de volgende resultaten:
Platform | Toevoegen na | Toevoegen voor | Misschien toevoegen |
---|---|---|---|
Windows Server 2016, Java 11 – Hotspot | 26ms | 40ms | 26ms |
Windows Server 2016, Java 8 – Hotspot | 27ms | 36ms | 21ms |
Windows Server 2016, Java 11 – OpenJ9 | 63ms | 81ms | 59ms |
Windows Server 2016, Java 8 – OpenJ9 | 66ms | 64ms | 55ms |