[java] String.contains in Java

String s1 = "The quick brown fox jumps over the lazy dog";
String s2 = "";
boolean b = s1.contains(s2);
System.out.println(b);

I run the Java code above, the b return true. Since s2 is empty, why does s1 contains s2?

I check the Java API, it write:

Returns true if and only if this string contains the specified sequence of char values.

Parameters:

s - the sequence to search for

Returns:

true if this string contains s, false otherwise

This question is related to java string

The answer is


I will answer your question using a math analogy:

In this instance, the number 0 will represent no value. If you pick a random number, say 15, how many times can 0 be subtracted from 15? Infinite times because 0 has no value, thus you are taking nothing out of 15. Do you have difficulty accepting that 15 - 0 = 15 instead of ERROR? So if we switch this analogy back to Java coding, the String "" represents no value. Pick a random string, say "hello world", how many times can "" be subtracted from "hello world"?


Thinking of a string as a set of characters, in mathematics the empty set is always a subset of any set.


The obvious answer to this is "that's what the JLS says."

Thinking about why that is, consider that this behavior can be useful in certain cases. Let's say you want to check a string against a set of other strings, but the number of other strings can vary.

So you have something like this:

for(String s : myStrings) {
   check(aString.contains(s));
}

where some s's are empty strings.

If the empty string is interpreted as "no input," and if your purpose here is ensure that aString contains all the "inputs" in myStrings, then it is misleading for the empty string to return false. All strings contain it because it is nothing. To say they didn't contain it would imply that the empty string had some substance that was not captured in the string, which is false.


no real explanation is given by Java (in either JavaDoc or much coveted code comments), but looking at the code, it seems that this is magic:

calling stack:

String.indexOf(char[], int, int, char[], int, int, int) line: 1591  
String.indexOf(String, int) line: 1564  
String.indexOf(String) line: 1546   
String.contains(CharSequence) line: 1934    

code:

/**
 * Code shared by String and StringBuffer to do searches. The
 * source is the character array being searched, and the target
 * is the string being searched for.
 *
 * @param   source       the characters being searched.
 * @param   sourceOffset offset of the source string.
 * @param   sourceCount  count of the source string.
 * @param   target       the characters being searched for.
 * @param   targetOffset offset of the target string.
 * @param   targetCount  count of the target string.
 * @param   fromIndex    the index to begin searching from.
 */
static int indexOf(char[] source, int sourceOffset, int sourceCount,
                   char[] target, int targetOffset, int targetCount,
                   int fromIndex) {
  if (fromIndex >= sourceCount) {
        return (targetCount == 0 ? sourceCount : -1);
  }
      if (fromIndex < 0) {
        fromIndex = 0;
      }
  if (targetCount == 0) {//my comment: this is where it returns, the size of the 
    return fromIndex;    // incoming string is 0,  which is passed in as targetCount
  }                      // fromIndex is 0 as well, as the search starts from the 
                         // start of the source string
    ...//the rest of the method 

Similarly:

"".contains("");     // Returns true.

Therefore, it appears that an empty string is contained in any String.