68

passing 0 as a limit argument prevents trailing empty strings, but how does one prevent leading empty strings?

for instance

String[] test = "/Test/Stuff".split("/");

results in an array with "", "Test", "Stuff".

Yeah, I know I could roll my own Tokenizer... but the API docs for StringTokenizer say

"StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split"

marathon
  • 7,881
  • 17
  • 74
  • 137

10 Answers10

51

Your best bet is probably just to strip out any leading delimiter:

String input = "/Test/Stuff";
String[] test = input.replaceFirst("^/", "").split("/");

You can make it more generic by putting it in a method:

public String[] mySplit(final String input, final String delim)
{
    return input.replaceFirst("^" + delim, "").split(delim);
}

String[] test = mySplit("/Test/Stuff", "/");
Joe Attardi
  • 4,381
  • 3
  • 39
  • 41
23

Apache Commons has a utility method for exactly this: org.apache.commons.lang.StringUtils.split

StringUtils.split()

Actually in our company we now prefer using this method for splitting in all our projects.

mbroshi
  • 969
  • 8
  • 21
adranale
  • 2,835
  • 1
  • 21
  • 39
6

I don't think there is a way you could do this with the built-in split method. So you have two options:

1) Make your own split

2) Iterate through the array after calling split and remove empty elements

If you make your own split you can just combine these two options

public List<String> split(String inString)
{
   List<String> outList = new ArrayList<>();
   String[]     test    = inString.split("/");

   for(String s : test)
   {
       if(s != null && s.length() > 0)
           outList.add(s);
   }

   return outList;
}

or you could just check for the delimiter being in the first position before you call split and ignore the first character if it does:

String   delimiter       = "/";
String   delimitedString = "/Test/Stuff";
String[] test;

if(delimitedString.startsWith(delimiter)){
    //start at the 1st character not the 0th
    test = delimitedString.substring(1).split(delimiter); 
}
else
    test = delimitedString.split(delimiter);
Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170
2

I think you shall have to manually remove the first empty string. A simple way to do that is this -

  String string, subString;
  int index;
  String[] test;

  string = "/Test/Stuff";
  index  = string.indexOf("/");
  subString = string.substring(index+1);

  test = subString.split("/"); 

This will exclude the leading empty string.

CodeBlue
  • 14,631
  • 33
  • 94
  • 132
  • 1
    But with this code, if an input string _didn't_ have a leading delimiter, you'd skip the first component. For example, `"Test/Stuff"` would yield just a single element, "Stuff". – Joe Attardi Feb 22 '12 at 05:45
  • Good point. In that case, an additional check would have to be made. – CodeBlue Feb 22 '12 at 05:55
1

When using JDK8 and streams, just add a skip(1) after the split. Following sniped decodes a (very wired) hex encoded string.

Arrays.asList("\\x42\\x41\\x53\\x45\\x36\\x34".split("\\\\x"))
    .stream()
    .skip(1) // <- ignore the first empty element
    .map(c->""+(char)Integer.parseInt(c, 16))
    .collect(Collectors.joining())
m_c
  • 59
  • 1
  • 9
1

Split method variants like split(regex, limit) can also produce empty strings at beginning or in middle of the resulting String array. Below code removes all such empty strings using streams api filter method in Java 8.

Sample code:

String[] tokens = s.split("/");
Arrays.stream(tokens)
.filter(s1 -> !s1.isEmpty())
.forEach(System.out::println);
hari862
  • 11
  • 3
1

I think there is no built-in function to remove blank string in Java. You can eliminate blank deleting string but it may lead to error. For safe you can do this by writing small piece of code as follow:

  List<String> list = new ArrayList<String>();

  for(String str : test) 
  {
     if(str != null && str.length() > 0) 
     {
         list.add(str);
     }
  }

  test = stringList.toArray(new String[list.size()]);
Rahul Tapali
  • 9,887
  • 7
  • 31
  • 44
0

This is how I've gotten around this problem. I take the string, call .toCharArray() on it to split it into an array of chars, and then loop through that array and add it to my String list (wrapping each char with String.valueOf). I imagine there's some performance tradeoff but it seems like a readable solution. Hope this helps!

 char[] stringChars = string.toCharArray(); 
 List<String> stringList = new ArrayList<>(); 

 for (char stringChar : stringChars) { 
      stringList.add(String.valueOf(stringChar)); 
 }
0

You can use StringTokenizer for this purpose...

String test1 = "/Test/Stuff";
        StringTokenizer st = new StringTokenizer(test1,"/");
        while(st.hasMoreTokens())
            System.out.println(st.nextToken());
Shashank Kadne
  • 7,993
  • 6
  • 41
  • 54
  • 2
    `StringTokenizer` is marked as deprecated in the API and probably shouldn't be used. – Hunter McMillen Feb 22 '12 at 05:37
  • Its not deprecated!!! http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html – Shashank Kadne Feb 22 '12 at 05:46
  • @McMillen can you please say from which version it is got deprecated. Actually I don't know this. – Chandra Sekhar Feb 22 '12 at 05:48
  • It's not _officially_ deprecated, but the Javadocs state "StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead." – Joe Attardi Feb 22 '12 at 05:50
  • 1
    @ShashankKadne It may not say deprecated but there is this exact line in the API page: `StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.` – Hunter McMillen Feb 22 '12 at 05:50
  • @HunterMcMillen:- Its use is discouraged in newer code, but I think that's not as strong a statement as saying it's deprecated. – Shashank Kadne Feb 22 '12 at 05:54
  • @ShashankKadne It means it _shouldn't_ be used. It would have been removed from the language except for the compatibility with older versions of Java. – Hunter McMillen Feb 22 '12 at 05:56
-2

You can only add statement like if(StringUtils.isEmpty(string)) continue; before print the string. My JDK version 1.8, no Blank will be printed. 5 this program gives me problems

3iL
  • 2,146
  • 2
  • 23
  • 47