3

I implement it by the following code, but I don't know whether there's a more efficient way to remove all blank spaces from a StringBuilder

private static StringBuilder removeBlankSpace(StringBuilder sb){
    for(int i=0;i<sb.length();++i){
        if(Character.isWhitespace(sb.charAt(i))){
            sb.deleteCharAt(i);
                            i--;
        }
    }
    return sb;
}
remy
  • 1,255
  • 6
  • 20
  • 27
  • 1
    Did u see this ? http://stackoverflow.com/questions/3396525/remove-empty-character-from-string – Dheeraj Joshi Apr 23 '12 at 05:56
  • You should create new StringBuilder in your function and copy all not white spaced characters. Method deleteCharAt remove one character and move rest of char array. Method should not modify input parameters!!! – Andrzej Jozwik Apr 23 '12 at 07:05

6 Answers6

11

You shouldn't call delete more than once - simply move each character down to its final location and then delete the range at the end.

static void removeBlankSpace(StringBuilder sb) {
  int j = 0;
  for(int i = 0; i < sb.length; i++) {
    if (!Character.isWhitespace(sb.charAt(i))) {
       sb.setCharAt(j++, sb.charAt(i));
    }
  }
  sb.delete(j, sb.length);
}
Keith Randall
  • 22,985
  • 2
  • 35
  • 54
  • One potential optimization: while `j` is 0, you only need to check for whitespace, without changing anything. So you might want to have one initial loop until you find the first whitespace, then the rest of your method as shown. – Jon Skeet Apr 23 '12 at 06:21
  • 1
    While we're into performance, it's probably more efficient, or at least it is explicitly efficient, to use `sb.setLength` in the end there, instead if `sb.delete`. – Marko Topolnik Apr 23 '12 at 07:38
  • @Jon: I think you mean `while j==i`. – Keith Randall Apr 23 '12 at 16:09
  • Obviously in this solution we are dealing with the method length() and not with length – keesp Oct 25 '21 at 10:36
3

EDIT: Leaving this answer in for posterity, but Keith Randall's O(n) solution is much nicer.

You may find it's more efficient to work from the far end - as that way by the time you remove early characters, you won't be copying whitespace from later.

Also, if your data tends to have multiple whitespace characters together, you may wish to spot that and call delete rather than deleteCharAt. So something like:

private static StringBuilder removeBlankSpace(StringBuilder sb) {
    int currentEnd = -1;
    for(int i = sb.length() - 1; i >= 0; i--) {
        if (Character.isWhitespace(sb.charAt(i))) {
            if (currentEnd == -1) {
                currentEnd = i + 1;
            }
        } else {
            // Moved from whitespace to non-whitespace
            if (currentEnd != -1) {
                sb.delete(i + 1, currentEnd);
                currentEnd = -1;
            }
        }
    }
    // All leading whitespace
    if (currentEnd != -1) {
        sb.delete(0, currentEnd);
    }
    return sb;
}
Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • thank you, but I don't know why I should work from the far end, can you explain that detailed? – remy Apr 23 '12 at 06:14
  • @remy: Suppose you have a string of a one space, then lots of non-space, then a million spaces. If you remove the first space first, you end up copying all of the spaces when you don't need to. As I've edited though, Keith's answer is much nicer :) – Jon Skeet Apr 23 '12 at 06:19
2

How about the following (assuming that you have your StringBuilder sb initialized):

sb = new StringBuilder(sb.toString().replaceAll("\\s", ""));
aviad
  • 8,229
  • 9
  • 50
  • 98
  • That will remove *everything* before the final space. So "hello there" becomes "there". I don't think that's what's required. It also *only* detects spaces. – Jon Skeet Apr 23 '12 at 05:59
  • That would work (after you've escaped the backslash in the literal), but it kinda defeats the point of starting with a StringBuilder... – Jon Skeet Apr 23 '12 at 06:13
  • @Jon Skeet, do you mean that performance-wise `String.replaceAll` is worse than looping over `StringBuilder` characters? – aviad Apr 23 '12 at 06:18
  • I mean that I suspect it's worse to call `toString()`, then `replaceAll`, then build a new `StringBuilder`. In particular, if there *aren't* any whitespace characters that's doing a lot of copying for no reason. – Jon Skeet Apr 23 '12 at 06:20
  • @Jon Skeet, I agree that it can be tuned (some validation will help). However, I still think that the performance is O(n) – aviad Apr 23 '12 at 06:26
  • Is it? Is that guaranteed anywhere in the docs for `String.replaceAll`? Maybe it is - I don't remember seeing anything written in the docs about the performance of regular expression replacement. Keith Randall's answer is far more clearly O(n) *and* doesn't have as much extra overhead. – Jon Skeet Apr 23 '12 at 06:30
  • @Jon Skeet, correct it is not guaranteed, but the source code of replaceAll on Windows implies that :) Moreover, I do not remember that `charAt` or `setCharAt` of the `AbstractStringBuilder` iimplementation guarantees you O(1) either. – aviad Apr 23 '12 at 07:03
  • 1
    Yes, you're right - that guarantee isn't stated. However, it's what an obvious, natural, naive implementation would give, whereas I wouldn't like to start guessing about regex performance. I still vastly prefer Keith's approach :) – Jon Skeet Apr 24 '12 at 05:28
1

Code to Remove Leading & Trailing spaces of a String

 int i = 0;
 int j = 0;

 for (; i < whiteSpcaTest.length();) {
   i = 0;
   if (Character.isWhitespace(whiteSpcaTest.charAt(i))) {
     whiteSpcaTest.deleteCharAt(i);

   } else {
     break;
   }
 }
 for (; j >= 0;) {
   j = whiteSpcaTest.length() - 1;
   if (Character.isWhitespace(whiteSpcaTest.charAt(j))) {
     whiteSpcaTest.deleteCharAt(j);

   } else {
     break;
   }

 }
Davide Pastore
  • 8,678
  • 10
  • 39
  • 53
0

The java string trim() method eliminates leading and trailing spaces. The unicode value of space character is '\u0020'. The trim() method in java string checks this unicode value before and after the string, if it exists then removes the spaces and returns the omitted string. For example:

public class StringTrimExample{  
public static void main(String args[]){  
String s1="  hello string   ";  
System.out.println(s1+"javatpoint");//without trim()  
System.out.println(s1.trim()+"javatpoint");//with trim()  
}}  

and the results:

  hello string   javatpoint
hello stringjavatpoint  
Sohrab
  • 1,348
  • 4
  • 13
  • 33
0

I think this way is quite concise:

void removeAll(StringBuilder sb, char c) {
  var length = sb.length();
  int i = 0;
  while (i < length) {
    if (sb.charAt(i) == c) {
      sb.deleteCharAt(i);
      length--;
    } else {
      i++;
    }
  }
}
Jan Tibar
  • 46
  • 5