15

My logs show this exception: ArrayIndexOutOfBoundsException: length=0; index=0 triggered by the following piece of code:

public static String getInitialsFromFullName(String fullName)
{
    String[] splitNames = fullName.split(" ");
    String firstName = splitNames[0]; <-- Here
    ...
}

I am trying to figure out the condition for which String.split returns an empty array. My understanding is that if no match is found, an array of size 1 with the original string is returned.

This is Java compiled for the Android build SDK version 21. I am looking forward to hear what obvious detail I am missing.

siger
  • 3,112
  • 1
  • 27
  • 42
  • 1
    http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String) and it looks like you found your answer :) it returns nothing if no match is found – thermite Jan 20 '15 at 00:23
  • 2
    http://ideone.com/jEiMFw < if fullName is separator `" "` (or separator * N `" ..multiple spaces "` ) – Selvin Jan 20 '15 at 00:25
  • @thermite I saw that documentation but I do not see where it mentions the special cases. Also, using Selvin's cool website we can see it is not correct: http://ideone.com/8mRkd4. – siger Jan 20 '15 at 00:39
  • @Selvin thank you, that was it. I am slightly ashamed I hadn't tried this basic case. Added a unit test and going to take a break. Add your comment as a question if you'd like! – siger Jan 20 '15 at 00:39
  • Not just whitespaces, even if the string equals the regex, it'll return empty array, like, `"a".split("a")` http://ideone.com/YTGEsv – srkavin Jan 20 '15 at 00:46
  • the space was only an example as it was used in an OP's code ... i wrote "fullName is separator" or "separator * N" ... – Selvin Jan 20 '15 at 01:18
  • Be careful when you forget that split expects a full blown regexp instead of _just a string_, because I tried splitting filenames on a dot, but I need to provide the pattern `"\\."` instead of `"."` for it to work; else it would match **everything** and just return and emptry array. – klaar Mar 24 '16 at 12:05

1 Answers1

27

split(regex) returns result of split(regex,0) where 0 is limit. Now according to documentation (limit is represented by n)

If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

(emphasis mine)

It means that in case of code like

"ababaa".split("a")

at first you will get array ["", "b","b","",""] but then trailing empty string swill be removed, so you will end up with array ["","b","b"]

BUT if your string contains text which can be matched by split pattern entirely, like

"ababab".split("ab")

at first resulting array will contain ["","","",""] (three splits), but then empty trailing strings will be removed. Since all of them are trailing empty strings all of them will be removed from array and empty array will be returned [] (array with size 0).

So to get empty array as result you need to split on string which is build from parts which can be matched by split pattern. This means that in case of yourString.split(" ") the yourString must contain only spaces (at least one, see BTW for more info)


BTW if original string would be empty "" and we call "".split("any-value") then splitting won't happen (split nothing makes no sense). In such case array containing original string [""] will be returned and that empty string will NOT be removed because it was not result of splitting.

In other words removing trailing empty strings makes sense only if these empty strings ware created as result of splitting, like "abaa".split("a") initially creates ["","b", "",""]. So when splitting didn't happen "cleanup" is not required. In such case result array will contain original string as explained in my earlier answer on this subject.

Pshemo
  • 122,468
  • 25
  • 185
  • 269