44

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
  • 302,674
  • 57
  • 556
  • 614
tmeisenh
  • 1,504
  • 1
  • 13
  • 11
  • 2
    Yes, and what is the question? – Arne Burmeister Apr 21 '10 at 13:54
  • 1
    `"foo".indexOf("")` returns 0 and `"foo".substring(0.0)` returns `""`. Seems consistent, I'd say. – Joachim Sauer Apr 21 '10 at 13:55
  • possible duplicate of http://stackoverflow.com/questions/2568625/indexof-method-returns-0-when-it-should-had-return-1-in-c-java – Adam Paynter Apr 21 '10 at 14:15
  • System.out.println("".indexOf("FOO")); <- this does return a -1, I think you might have mixed up what you expected for a result? – ProfessionalAmateur Apr 21 '10 at 14:49
  • For something truly mindboggling, `"".contains("")` is `true`. So the empty string contains something... and yet it's empty!!! – polygenelubricants Apr 21 '10 at 14:51
  • @polygenelubricants: then again `a.contains(a)` is true for all Strings. – Joachim Sauer Apr 21 '10 at 14:55
  • @Adam Paynter - yes it looks like I did re-raise this. My search omitted C#. @ProfessionalAmateur - My original test was the opposite of what you had. @polygenelubricants - lol my mind is blown!! :P – tmeisenh Apr 21 '10 at 14:56
  • @Adam (again) - Actually many thanks for pointing out that C# link. Of note is that the C# documentation explicitly states that the empty string returns 0. In the Case of C# that would be expected behavior since it is documented. – tmeisenh Apr 21 '10 at 14:58
  • @Joachim: yes, but they're not `isEmpty()`. That's what I'm trying to contrast, `s1.isEmpty() && s1.contains(s2)` can be `true`. – polygenelubricants Apr 21 '10 at 15:06

7 Answers7

133

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
  • 405,095
  • 59
  • 585
  • 614
  • 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
34

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

T .
  • 4,874
  • 3
  • 23
  • 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
  • @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
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,696
  • 16
  • 35
  • 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,715
  • 1
  • 37
  • 53
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
  • 2,040
  • 2
  • 21
  • 29
  • 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,526
  • 1
  • 8
  • 18
0

This question is actually two questions:

  1. Why should a string contain the empty string?
  2. Why should the empty string be found specifically at index zero?

Answering #1:

A string contains the empty string in order to be in accordance with Set Theory, according to which:

The empty set is a subset of every set including itself.

This also means that even the empty string contains the empty string, and the following statement proves it:

assert "".indexOf( "" ) == 0;

I am not sure why mathematicians have decided that it should be so, but I am pretty sure they have their reasons, and it appears that these reasons can be explained in layman's terms, as various youtube videos seem to do, (for example, https://www.youtube.com/watch?v=1nBKadtFViM) although I have not actually viewed any of those videos, because #AintNoBodyGotNoTimeFoDat.

Answering #2:

The empty string can be found specifically at index zero of any string, because why not? In other words, if not at index zero, then at which index? Index zero is as good as any other index, and index zero is guaranteed to be a valid index for all strings except for the trifling exception of the empty string.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142