Java: Check if String Starts with Another String - Stack Abuse

Java: Check if String Starts with Another String

Introduction

In this article, we'll take a look at how to check if a String starts with another String in Java.

This is is a fairly common task in programming, and is very similar to checking if a string contains a substring. For example, this can come in useful if we want to filter out all of the words out of a huge selection starting with a specific String.

However, this problem differs from checking if a String only contains a specific substring, and there's a few ways to do so in both Core Java and Apache Commons:

Core Java

Let's start off with solutions that can easily be implemented using Core Java.

String.startsWith()

This method does exactly what we need it to do - and is the most common way to solve this problem. It returns a boolean, which indicates if the string begins with the provided keyword:

String string = "every end is a new beginning";

System.out.println(string.toLowerCase().startsWith("new".toLowerCase()));
System.out.println(string.toLowerCase().startsWith("EVERY".toLowerCase()));
System.out.println(string.toLowerCase().startsWith(""));

Running this outputs:

false
true
true

Note: If the parameter passed is an empty string, the result is always true.

Of course, this method is case-sensitive, and should always be used in pair with toLowerCase() or toUpperCase() when we're just looking for a specific keyword and don't care if the cases match.

Stream.anyMatch()

Another thing we could check for is if a String starts with multiple substrings. Say, we have a few standardized prefixes - we can use make a Stream of substrings, and run an anyMatch() check for the String we're checking in.

Let's take a look at how to do that:

String string = "every end is a new beginning";
System.out.println(Stream.of("every", "none").anyMatch(string::startsWith));

Here, we've created a Stream of possible substrings, and checked if any of them are present at the start of the given String with a method reference call to startsWith().

This code results in:

true

String.indexOf()

The indexOf() method can be quite useful in solving a variety of problems concerning substrings, including checking if a string begins with a specific one.

The method returns the index of the first occurrence of a substring within a string if it's found, otherwise -1.

It has a few overloaded variants from which we'll only be needing just the one below, since the other ones have different appliances:

public int indexOf(String str)

If the indexOf() method returns 0, that means our String begins with another we've given it as a parameter.

For example:

String string = "Just a sample String";

System.out.println(string.toLowerCase().indexOf("just".toLowerCase()));
System.out.println(string.toLowerCase().indexOf("String".toLowerCase()));
System.out.println(string.toLowerCase().indexOf("something else".toLowerCase()));

will output:

0
14
-1
  • The answer we're looking for is found within our first example, as it returned 0 - exactly what we need, meaning our string begins with a given parameter.
  • We can clearly see that in the second example, the "String" parameter we've given is indeed found within our String, but at the position 14, which is not what we were looking for.
  • The third example isn't even contained within our String, and returns -1.

Using the information above, we can accumulate the logic in a function:

public static boolean startsWithSubstring(String text, String keyword) {
    return text.toLowerCase().indexOf(keyword.toLowerCase()) == 0;
}

Pattern with Regex and Matcher

The Pattern class is a compiled representation of a regular expression. With this Pattern we can then generate an engine that recognizes said regular expression - we can generate a Matcher.

We'll be using the find() method in combination with start() to check if our Matcher instance begins with a given String:

public static boolean startsWithSubstring(String text, String keyword) {
    String inputString = text.toLowerCase();
    String subString = keyword.toLowerCase();


    // We compile the regular expression to generate a Pattern object
    Pattern pattern = Pattern.compile(subString);

    // Then we generate an engine (Matcher) which can be used
    // to recognize and match the regular expression it was
    // generated from (in our case "this").
    Matcher matcher = pattern.matcher(inputString);

    // find() compares the assigned and compiled patterns, and will return a boolean value indicating if they match.
    // That's where the start() method comes into play; it returns the index of the position 
    // where the two strings matched, or -1 if it's not found.
    if (matcher.find()) {
          return matcher.start() == 0;
    }
    return false;
}

Let's test this method out:

System.out.println(startsWithSubstring(string, "every"));

This results in:

true

Using a for-loop

A more low-level way of solving this problem would be using a for-loop.

We iterate through the whole length of the search string, we compare the first searchString.length() characters and return true if the all match.

Let's see how this all works in code:

public static boolean startsWithSubstring(String text, String keyword) {
    for (int i = 0; i < keyword.length(); i++) {
          if (text.toLowerCase().charAt(i) != keyword.toLowerCase().charAt(i)) {
              System.out.println("String doesn't start with " + "\"" + keyword + "\"");
        return false;
          } else if (i == keyword.length() - 1) {
              System.out.println("String starts with " + "\"" + keyword + "\"");
              return true;
          }
    }
    return false;
}

Git Essentials

Check out this hands-on, practical guide to learning Git, with best-practices and industry-accepted standards. Stop Googling Git commands and actually learn it!

Let's test this method out:

String string = "Just a sample String";

System.out.println(startsWithSubstring(string, "just"));
System.out.println(startsWithSubstring(string, "String"));
System.out.println(startsWithSubstring(string, "something else"));

This results in:

String starts with "just"
true
String doesn't start with "String"
false
String doesn't start with "something else"
false

By default, if we hadn't used toLowerCase() to even out the letters in the method itself, this approach would've been case-sensitive.

Apache Commons

The Apache Commons library provides functionality that expands on the core Java Framework. It's one of the top third-party libraries and is present in many modern Java projects.

Apache Commons offers the StringUtils class, which contains many methods used to manipulate strings. Most of these methods are quite similar to the ones found in java.lang.String. The main difference being that all methods within the StringUtils class are null-safe.

However, for this task we'll need only a few methods from this class:

  1. .indexOf()
  2. .startsWith()
  3. .startsWithIgnoreCase().

If not already, include the Apache Commons library in your project by adding a dependency to your pom.xml file if you're using Maven:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

Or by adding it to Gradle:

compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'

StringUtils.indexOf()

This method has a few overloaded variants all of which return an int value indicating the index of the first occurrence of the substring, or -1 if the substring doesn't appear at all.

We'll be focusing on the following variant of this method:

public static int indexOf(CharSequence seq, CharSequence searchSeq)

This method takes two Strings/CharSequences.

The seq parameter represents the String we'll be searching through to find searchSeq. Same logic applies as before - if this function returns 0, we'll know that our string begins with a given searchSeq substring.

Also keep in mind that this method, like its counterpart, is also case-sensitive, so using .toLowerCase() or .toUpperCase() is required to achieve a case-insensitive behavior.

Using this method is very similar to using the indexOf() from java.lang.String:

String string = "a simple string to search in";

System.out.println(StringUtils.indexOf(string.toLowerCase(), "a simple".toLowerCase()));
System.out.println(StringUtils.indexOf(string.toLowerCase(), "string".toLowerCase()));
System.out.println(StringUtils.indexOf(string.toLowerCase(), "something".toLowerCase()));

This will yield:

0
9
-1

And thus, we can use this as a convenience method:

public static boolean startsWithSubstring(String text, String keyword) {
    return StringUtils.indexOf(text.toLowerCase(), keyword.toLowerCase()) == 0;
}

StringUtils.startsWith()

This method does exactly what you'd expect. It's also case-sensitive like it's predecessors, and accepts the same two parameters.

It returns true if the text begins with the keyword, or false if it doesn't.

Comparing two null values will result in true:

String string = "a simple string to search in";

System.out.println(StringUtils.startsWith(string.toLowerCase(), "A SIMPLE"));
System.out.println(StringUtils.startsWith(string.toLowerCase(), "A SIMPLE".toLowerCase()));
System.out.println(StringUtils.startsWith(null, null));

Running this will output:

false
true
true

StringUtils.startsWithAny()

The startsWithAny() doesn't have a counterpart in the java.lang.String class, and is unique to StringUtils.

However, it is very close to what we did with anyMatch() on a Stream - It checks if a String begins with any of the given substrings, returning true or false appropriately.

It's also case-sensitive:

String string = "a simple string to search in";

System.out.println(StringUtils.startsWithAny(string, "something", "a simple"));
System.out.println(StringUtils.startsWithAny(string, "something", "string"));
System.out.println(StringUtils.startsWithAny(string, "something", null));
System.out.println(StringUtils.startsWithAny(string, "something", ""));

Running this gives us:

true
false
false
true

StringUtils.startsWithIgnoreCase()

Since it can get annoying to call toLowerCase() all the time on Strings during comparison, you can alternatively sue the startsWithIgnoreCase() method.

Like the startsWith() method from the same class, it takes two Strings (or CharSequence) types, and the return value is true or false depending on if the text actually starts with the provided keyword:

String string = "a simple string to search in";

System.out.println(StringUtils.startsWithIgnoreCase(string, "something"));
System.out.println(StringUtils.startsWithIgnoreCase(string, "A SIMPLE"));
System.out.println(StringUtils.startsWithIgnoreCase(string, ""));
System.out.println(StringUtils.startsWithIgnoreCase(string, null));

Running this outputs:

false
true
true
false

Conclusion

In this article, we've gone over all the different method of checking if a String begins with another String, both in core Java and utilizing the Apache Commons library.

In conclusion, there are many different ways to accomplish this task. In reality, we could have combined any of the methods above in order to find an index that a substring starts on, and from there on check where the substring is positioned at.

Most of the time, just using the startsWith() methods, or startsWithIgnoreCase() would be enough to solve this problem and would also give the cleanest, shortest code.

Last Updated: January 18th, 2021

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Want a remote job?

    Prepping for an interview?

    • Improve your skills by solving one coding problem every day
    • Get the solutions the next morning via email
    • Practice on actual problems asked by top companies, like:
     
     
     

    Git Essentials

    Check out this hands-on, practical guide to learning Git, with best-practices and industry-accepted standards. Stop Googling Git commands and actually learn it!

    © 2013-2021 Stack Abuse. All rights reserved.