20

Have following Java code,that creates StringBuilder with "\n",i.e. carriage return delimiters:

while (scanner.hasNextLine()){
    sb.append(scanner.nextLine()).append("\n");
}

It's occurred,that after last String(line) had "\n" symbol.

How to gracefully remove last "\n" from resulting StringBuilder object?

thanks.

Jonik
  • 80,077
  • 70
  • 264
  • 372
sergionni
  • 13,290
  • 42
  • 132
  • 189

7 Answers7

25

This has always worked for me

sb.setLength(sb.length() - 1);

Operation is pretty lightweight, internal value holding current content size will just be decreased by 1.

Also, check length value before doing it if you think buffer may be empty.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
  • 1
    This approach is interesting, although the length check later on seems a downside. – cherouvim Oct 16 '10 at 17:04
  • @cherouvim Yep. On the other hand, you don't allocate unnecessary memory, like with 'trim' or 'join'. Although, your answer is pretty good too, I often use that approach myself. – Nikita Rybak Oct 16 '10 at 17:08
  • In extremely high performance situations where I'd have to add millions of elements on sb I'd definitelly use your approach since it has the quickest loop (no if check). – cherouvim Oct 16 '10 at 17:10
  • The length call will likely be replaced with a direct variable lookup at runtime... and the check for length == 0 after only happens once, unlike other solutions where an if is done each iteration of the loop. So no real downsides compared to other ways. – TofuBeer Oct 16 '10 at 17:11
  • in Windows this delete only 0A char, but you still have 0D at the end – GML-VS Sep 11 '16 at 18:31
  • To be "more robust" you can use System.Environment.NewLine.Length to remove the system's newline string. – Ryan Gregg Feb 15 '17 at 21:51
13

If you're working with a small enough number of lines, you can put all the lines in a List<String> and then use StringUtils.join(myList, "\n");

Another option is to trim() the resulting string.

Update after discovering guava's neat Joiner class:

Joiner.on('\n').join(myList)

Community
  • 1
  • 1
oksayt
  • 4,333
  • 1
  • 22
  • 41
4

You could build the result without a newline to get rid of:

String separator = "";
while (scanner.hasNextLine()){
    sb.append(separator).append(scanner.nextLine());
    separator = "\n";
}
rsp
  • 23,135
  • 6
  • 55
  • 69
3

sb.deleteCharAt(sb.length()-1);

Mikos
  • 8,455
  • 10
  • 41
  • 72
3

Instead of having to remove it you could simply never add it.

while (scanner.hasNextLine()) {
    if (sb.length()>0) sb.append("\n");
    sb.append(scanner.nextLine());
}
cherouvim
  • 31,725
  • 15
  • 104
  • 153
2
bool isFirst = true;
while (scanner.hasNextLine()){
  if(!isFirst)
    sb.append("\n"));
  else
    isFirst = false;

  sb.append(scanner.nextLine());

}
Stephen Swensen
  • 22,107
  • 9
  • 81
  • 136
1
if (scanner.hasNextLine()) 
  sb.append(scanner.nextLine());
while (scanner.hasNextLine()){
  sb.append("\n").append(scanner.nextLine());
}
andersoj
  • 22,406
  • 7
  • 62
  • 73
  • The problem here is the code duplication for appending. In this example it's trivial, but in other cases it may be not. So duplicating is not good. – cherouvim Oct 16 '10 at 16:59
  • Agreed. I think the `trim()` solution is inelegant, and mine suffers from code duplication. Maybe `join()` is the best... – andersoj Oct 16 '10 at 17:37