43

I'm curious why the String.indexOf is returning a 0 (instead of -1) when asking for the index of an empty string within a string.

The Javadocs only say this method returns the index in this string of the specified string, -1 if the string isn't found.

To me this behavior seems highly unexpected, I would have expected a -1. Any ideas why this unexpected behavior is going on? I would at the least think this is worth a note in the method's Javadocs...

System.out.println("FOO".indexOf("")); // outputs 0 wtf!!!
System.out.println("FOO".indexOf("bar")); // outputs -1 as expected
System.out.println("FOO".indexOf("F")); // outputs 0 as expected
System.out.println("".indexOf("")); // outputs 0 as expected, I think
Joachim Sauer
  • 291,719
  • 55
  • 540
  • 600
tmeisenh
  • 1,474
  • 1
  • 13
  • 11

6 Answers6

131

The empty string is everywhere, and nowhere. It is within all strings at all times, permeating the essence of their being, yet as you seek it you shall never catch a glimpse.

How many empty strings can you fit at the beginning of a string? Mu

The student said to the teacher,

Teacher, I believe that I have found the nature of the empty string. The empty string is like a particle of dust, and it floats freely through a string as dust floats freely through the room, glistening in a beam of sunlight.

The teacher responded to the student,

Hmm. A fine notion. Now tell me, where is the dust, and where is the sunlight?

The teacher struck the student with a strap and instructed him to continue his meditation.

Pointy
  • 389,373
  • 58
  • 564
  • 602
  • 8
    We seriously need more users like you on SO. I read one of your answers on a related post, and have been cracking up for the last 10mn from other answers on your profile. Well done, Zen Master. – JWiley Jun 01 '12 at 17:04
  • 1
    But how does one count the number of angels that can dance within the empty string? – Ed B Jun 04 '15 at 11:34
  • 3
    I love this. I'll never forget an answer like this. – racl101 May 25 '16 at 17:01
32

Well, if it helps, you can think of "FOO" as "" + "FOO".

T .
  • 4,754
  • 3
  • 21
  • 36
  • 5
    Indeed, the empty string can be found between any two adjacent characters in a string as well as at the start and end. The first such instance is the very start of the string, namely position 0. – Joey Apr 21 '10 at 13:55
  • I would say empty string occurs zero times in the string Ali G but obviously I'm wrong. – tmeisenh Apr 21 '10 at 14:10
  • 3
    @Ali G: 4 distinct times: At position 0, 1, 2, and 3 as you can easily verify by calling `.substring(0,0)` up to `.substring(3,3)` on `"FOO"`. – Joachim Sauer Apr 21 '10 at 14:11
  • 1
    StringTokenizer st = new StringTokenizer("FOO",""); System.out.println(st.countTokens()); // outputs 1 So it looks like the empty string exists once according to StringTokenizer – tmeisenh Apr 21 '10 at 14:42
  • @Johannes, @tmeisenh, @Joachim: great answers, definitely agree ;-) – Armand Apr 21 '10 at 14:44
  • @Joachim: However, you can concatenate the empty string any number of times at any position of a string and still get the desired result. – Joey Apr 21 '10 at 14:46
  • As funny as the accepted answer is. I think this is more succinct and clear for newbies like me. – racl101 May 25 '16 at 20:50
1

int number_of_empty_strings_in_string_named_text = text.length() + 1

All characters are separated by an empty String. Additionally empty String is present at the beginning and at the end.

ctomek
  • 1,626
  • 15
  • 30
  • Now I see that the same description is in Joey's comment, but still I think it's a good idea to put this in a new answer, because that's the only answer that really explains how it works. @Joey if you want to put this answer as your own and delete mine please let me know because you were first with that. – ctomek Dec 03 '15 at 13:24
0

Using an algebraic approach, "" is the neutral element of string concatenation: x + "" == x and "" + x == x (although + is non commutative here).

Then it must also be:

x.indexOf ( y ) == i and i != -1 
<==> x.substring ( 0, i ) + y + x.substring ( i + y.length () ) == x

when y = "", this holds if i == 0 and x.substring ( 0, 0 ) == "". I didn't design Java, but I guess mathematicians participated in it...

zakmck
  • 2,313
  • 32
  • 40
0

By using the expression "", you are actually referring to a null string. A null string is an ethereal tag placed on something that exists only to show that there is a lack of anything at this location.

So, by saying "".indexOf( "" ), you are really asking the interpreter:

Where does a string value of null exist in my null string?

It returns a zero, since the null is at the beginning of the non-existent null string.

To add anything to the string would now make it a non-null string... null can be thought of as the absence of everything, even nothing.

exoboy
  • 1,990
  • 2
  • 20
  • 28
  • So what's the difference between a "null string" and `null`? Don't we say "empty string" rather than "null string" specifically to avoid confusion with `null`? – nnnnnn Dec 24 '13 at 01:26
  • Check out this explanation: http://stackoverflow.com/questions/4802015/difference-between-null-and-java-string – exoboy Dec 27 '13 at 18:04
0

if we look inside of String implementation for a method "foo".indexOf(""), we arrive at this method:

public int indexOf(String str) {
    byte coder = coder();
    if (coder == str.coder()) {
        return isLatin1() ? StringLatin1.indexOf(value, str.value)
                          : StringUTF16.indexOf(value, str.value);
    }
    if (coder == LATIN1) {  // str.coder == UTF16
        return -1;
    }
    return StringUTF16.indexOfLatin1(value, str.value);
}

If we look inside of any of the called indexOf(value, str.value) methods we find a condition that says:

if the second parameter (string we are searching for) length is 0 return 0:

 public static int indexOf(byte[] value, byte[] str) {
    if (str.length == 0) {
        return 0;
    }
    ...

This is just defensive coding for an edge case, and it is necessary because in the next method that is called to do actual searching by comparing bytes of the string (string is a byte array) it would otherwise have resulted in an ArrayIndexOutOfBounds exception:

public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
        byte first = str[0];
...
J Asgarov
  • 2,095
  • 1
  • 7
  • 15