views:

111

answers:

7

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.

+7  A: 

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
This approach is interesting, although the length check later on seems a downside.
cherouvim
@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
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
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
@TofuBeer: I agree. My concern was related to code clarity.
cherouvim
+1  A: 
if (scanner.hasNextLine()) 
  sb.append(scanner.nextLine());
while (scanner.hasNextLine()){
  sb.append("\n").append(scanner.nextLine());
}
andersoj
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
Agreed. I think the `trim()` solution is inelegant, and mine suffers from code duplication. Maybe `join()` is the best...
andersoj
+6  A: 

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.

oksayt
+1 better than mine, assuming the `List<String>` can be known / stored reasonably.
andersoj
actually, can't find method join for StringUtils(that is sringframework class)
sergionni
Sorry that was unclear, I was referring to the apache commons-lang library. I put the link in the answer.
oksayt
ok, now i see,its' apache lib, unfortunately we don't have in our project
sergionni
+2  A: 
bool isFirst = true;
while (scanner.hasNextLine()){
  if(!isFirst)
    sb.append("\n"));
  else
    isFirst = false;

  sb.append(scanner.nextLine());

}
Stephen Swensen
neat way of getting rid of `else isFirst = false;`: `if (!isFirst | (isFirst = false))`
aioobe
@aioobe nice, i dig it
Stephen Swensen
A: 

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

Mikos
That will work only if content has been added on sb.
cherouvim
+2  A: 

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
+3  A: 

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