[java] How can I check if a single character appears in a string?

In Java is there a way to check the condition:

"Does this single character appear at all in string x"

without using a loop?

This question is related to java validation string character

The answer is


Is the below what you were looking for?

int index = string.indexOf(character);
return index != -1;

You can use 2 methods from the String class.

  • String.contains() which checks if the string contains a specified sequence of char values
  • String.indexOf() which returns the index within the string of the first occurence of the specified character or substring or returns -1 if the character is not found (there are 4 variations of this method)

Method 1:

String myString = "foobar";
if (myString.contains("x") {
    // Do something.
}

Method 2:

String myString = "foobar";
if (myString.indexOf("x") >= 0 {
    // Do something.
}

Links by: Zach Scrivena


I'm not sure what the original poster is asking exactly. Since indexOf(...) and contains(...) both probably use loops internally, perhaps he's looking to see if this is possible at all without a loop? I can think of two ways off hand, one would of course be recurrsion:

public boolean containsChar(String s, char search) {
    if (s.length() == 0)
        return false;
    else
        return s.charAt(0) == search || containsChar(s.substring(1), search);
}

The other is far less elegant, but completeness...:

/**
 * Works for strings of up to 5 characters
 */
public boolean containsChar(String s, char search) {
    if (s.length() > 5) throw IllegalArgumentException();

    try {
        if (s.charAt(0) == search) return true;
        if (s.charAt(1) == search) return true;
        if (s.charAt(2) == search) return true;
        if (s.charAt(3) == search) return true;
        if (s.charAt(4) == search) return true;
    } catch (IndexOutOfBoundsException e) {
        // this should never happen...
        return false;
    }
    return false;
}

The number of lines grow as you need to support longer and longer strings of course. But there are no loops/recurrsions at all. You can even remove the length check if you're concerned that that length() uses a loop.


String.contains(String) or String.indexOf(String) - suggested

"abc".contains("Z"); // false - correct
"zzzz".contains("Z"); // false - correct
"Z".contains("Z"); // true - correct
"and".contains(""); // true - correct
"and".contains(""); // false - correct
"and".indexOf(""); // 0 - correct
"and".indexOf(""); // -1 - correct

String.indexOf(int) and carefully considered String.indexOf(char) with char to int widening

"and".indexOf("".charAt(0)); // 0 though incorrect usage has correct output due to portion of correct data
"and".indexOf("".charAt(0)); // 0 -- incorrect usage and ambiguous result
"and".indexOf("".codePointAt(0)); // -1 -- correct usage and correct output

The discussions around character is ambiguous in Java world

can the value of char or Character considered as single character?

No. In the context of unicode characters, char or Character can sometimes be part of a single character and should not be treated as a complete single character logically.

if not, what should be considered as single character (logically)?

Any system supporting character encodings for Unicode characters should consider unicode's codepoint as single character.

So Java should do that very clear & loud rather than exposing too much of internal implementation details to users.

String class is bad at abstraction (though it requires confusingly good amount of understanding of its encapsulations to understand the abstraction and hence an anti-pattern).

How is it different from general char usage?

char can be only be mapped to a character in Basic Multilingual Plane.

Only codePoint - int can cover the complete range of Unicode characters.

Why is this difference?

char is internally treated as 16-bit unsigned value and could not represent all the unicode characters using UTF-16 internal representation using only 2-bytes. Sometimes, values in a 16-bit range have to be combined with another 16-bit value to correctly define character.

Without getting too verbose, the usage of indexOf, charAt, length and such methods should be more explicit. Sincerely hoping Java will add new UnicodeString and UnicodeCharacter classes with clearly defined abstractions.

Reason to prefer contains and not indexOf(int)

  1. Practically there are many code flows that treat a logical character as char in java.
  2. In Unicode context, char is not sufficient
  3. Though the indexOf takes in an int, char to int conversion masks this from the user and user might do something like str.indexOf(someotherstr.charAt(0))(unless the user is aware of the exact context)
  4. So, treating everything as CharSequence (aka String) is better
    public static void main(String[] args) {
        System.out.println("and".indexOf("".charAt(0))); // 0 though incorrect usage has correct output due to portion of correct data
        System.out.println("and".indexOf("".charAt(0))); // 0 -- incorrect usage and ambiguous result
        System.out.println("and".indexOf("".codePointAt(0))); // -1 -- correct usage and correct output
        System.out.println("and".contains("")); // true - correct
        System.out.println("and".contains("")); // false - correct
    }

Is the below what you were looking for?

int index = string.indexOf(character);
return index != -1;

package com;
public class _index {

    public static void main(String[] args) {
        String s1="be proud to be an indian";
        char ch=s1.charAt(s1.indexOf('e'));
        int count = 0; 
        for(int i=0;i<s1.length();i++) {
            if(s1.charAt(i)=='e'){
                System.out.println("number of E:=="+ch);
                count++;
            }
        }
        System.out.println("Total count of E:=="+count);
    }
}

If you see the source code of indexOf in JAVA:

public int indexOf(int ch, int fromIndex) {

        final int max = value.length;

        if (fromIndex < 0) {

            fromIndex = 0;

        } else if (fromIndex >= max) {

            // Note: fromIndex might be near -1>>>1.

            return -1;

        }


        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {

            // handle most cases here (ch is a BMP code point or a

            // negative value (invalid code point))

            final char[] value = this.value;

            for (int i = fromIndex; i < max; i++) {

                if (value[i] == ch) {

                    return i;

                }

            }

            return -1;

        } else {

            return indexOfSupplementary(ch, fromIndex);

        }

    }

you can see it uses a for loop for finding a character. Note that each indexOf you may use in your code, is equal to one loop.

So, it is unavoidable to use loop for a single character.

However, if you want to find a special string with more different forms, use useful libraries such as util.regex, it deploys stronger algorithm to match a character or a string pattern with Regular Expressions. For example to find an email in a string:

String regex = "^(.+)@(.+)$";
 
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(email);

If you don't like to use regex, just use a loop and charAt and try to cover all cases in one loop.

Be careful recursive methods has more overhead than loop, so it's not recommended.


Yes, using the indexOf() method on the string class. See the API documentation for this method


Yes, using the indexOf() method on the string class. See the API documentation for this method


  • String.contains() which checks if the string contains a specified sequence of char values
  • String.indexOf() which returns the index within the string of the first occurence of the specified character or substring (there are 4 variations of this method)

You won't be able to check if char appears at all in some string without atleast going over the string once using loop / recursion ( the built-in methods like indexOf also use a loop )

If the no. of times you look up if a char is in string x is more way more than the length of the string than I would recommend using a Set data structure as that would be more efficient than simply using indexOf

String s = "abc";

// Build a set so we can check if character exists in constant time O(1)
Set<Character> set = new HashSet<>();
int len = s.length();
for(int i = 0; i < len; i++) set.add(s.charAt(i));

// Now we can check without the need of a loop
// contains method of set doesn't use a loop unlike string's contains method
set.contains('a') // true
set.contains('z') // false

Using set you will be able to check if character exists in a string in constant time O(1) but you will also use additional memory ( Space complexity will be O(n) ).


  • String.contains() which checks if the string contains a specified sequence of char values
  • String.indexOf() which returns the index within the string of the first occurence of the specified character or substring (there are 4 variations of this method)

I'm not sure what the original poster is asking exactly. Since indexOf(...) and contains(...) both probably use loops internally, perhaps he's looking to see if this is possible at all without a loop? I can think of two ways off hand, one would of course be recurrsion:

public boolean containsChar(String s, char search) {
    if (s.length() == 0)
        return false;
    else
        return s.charAt(0) == search || containsChar(s.substring(1), search);
}

The other is far less elegant, but completeness...:

/**
 * Works for strings of up to 5 characters
 */
public boolean containsChar(String s, char search) {
    if (s.length() > 5) throw IllegalArgumentException();

    try {
        if (s.charAt(0) == search) return true;
        if (s.charAt(1) == search) return true;
        if (s.charAt(2) == search) return true;
        if (s.charAt(3) == search) return true;
        if (s.charAt(4) == search) return true;
    } catch (IndexOutOfBoundsException e) {
        // this should never happen...
        return false;
    }
    return false;
}

The number of lines grow as you need to support longer and longer strings of course. But there are no loops/recurrsions at all. You can even remove the length check if you're concerned that that length() uses a loop.


String temp = "abcdefghi";
if(temp.indexOf("b")!=-1)
{
   System.out.println("there is 'b' in temp string");
}
else
{
   System.out.println("there is no 'b' in temp string");
}

If you see the source code of indexOf in JAVA:

public int indexOf(int ch, int fromIndex) {

        final int max = value.length;

        if (fromIndex < 0) {

            fromIndex = 0;

        } else if (fromIndex >= max) {

            // Note: fromIndex might be near -1>>>1.

            return -1;

        }


        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {

            // handle most cases here (ch is a BMP code point or a

            // negative value (invalid code point))

            final char[] value = this.value;

            for (int i = fromIndex; i < max; i++) {

                if (value[i] == ch) {

                    return i;

                }

            }

            return -1;

        } else {

            return indexOfSupplementary(ch, fromIndex);

        }

    }

you can see it uses a for loop for finding a character. Note that each indexOf you may use in your code, is equal to one loop.

So, it is unavoidable to use loop for a single character.

However, if you want to find a special string with more different forms, use useful libraries such as util.regex, it deploys stronger algorithm to match a character or a string pattern with Regular Expressions. For example to find an email in a string:

String regex = "^(.+)@(.+)$";
 
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(email);

If you don't like to use regex, just use a loop and charAt and try to cover all cases in one loop.

Be careful recursive methods has more overhead than loop, so it's not recommended.


String temp = "abcdefghi";
if(temp.indexOf("b")!=-1)
{
   System.out.println("there is 'b' in temp string");
}
else
{
   System.out.println("there is no 'b' in temp string");
}

If you need to check the same string often you can calculate the character occurrences up-front. This is an implementation that uses a bit array contained into a long array:

public class FastCharacterInStringChecker implements Serializable {
private static final long serialVersionUID = 1L;

private final long[] l = new long[1024]; // 65536 / 64 = 1024

public FastCharacterInStringChecker(final String string) {
    for (final char c: string.toCharArray()) {
        final int index = c >> 6;
        final int value = c - (index << 6);
        l[index] |= 1L << value;
    }
}

public boolean contains(final char c) {
    final int index = c >> 6; // c / 64
    final int value = c - (index << 6); // c - (index * 64)
    return (l[index] & (1L << value)) != 0;
}}

You won't be able to check if char appears at all in some string without atleast going over the string once using loop / recursion ( the built-in methods like indexOf also use a loop )

If the no. of times you look up if a char is in string x is more way more than the length of the string than I would recommend using a Set data structure as that would be more efficient than simply using indexOf

String s = "abc";

// Build a set so we can check if character exists in constant time O(1)
Set<Character> set = new HashSet<>();
int len = s.length();
for(int i = 0; i < len; i++) set.add(s.charAt(i));

// Now we can check without the need of a loop
// contains method of set doesn't use a loop unlike string's contains method
set.contains('a') // true
set.contains('z') // false

Using set you will be able to check if character exists in a string in constant time O(1) but you will also use additional memory ( Space complexity will be O(n) ).


I'm not sure what the original poster is asking exactly. Since indexOf(...) and contains(...) both probably use loops internally, perhaps he's looking to see if this is possible at all without a loop? I can think of two ways off hand, one would of course be recurrsion:

public boolean containsChar(String s, char search) {
    if (s.length() == 0)
        return false;
    else
        return s.charAt(0) == search || containsChar(s.substring(1), search);
}

The other is far less elegant, but completeness...:

/**
 * Works for strings of up to 5 characters
 */
public boolean containsChar(String s, char search) {
    if (s.length() > 5) throw IllegalArgumentException();

    try {
        if (s.charAt(0) == search) return true;
        if (s.charAt(1) == search) return true;
        if (s.charAt(2) == search) return true;
        if (s.charAt(3) == search) return true;
        if (s.charAt(4) == search) return true;
    } catch (IndexOutOfBoundsException e) {
        // this should never happen...
        return false;
    }
    return false;
}

The number of lines grow as you need to support longer and longer strings of course. But there are no loops/recurrsions at all. You can even remove the length check if you're concerned that that length() uses a loop.


To check if something does not exist in a string, you at least need to look at each character in a string. So even if you don't explicitly use a loop, it'll have the same efficiency. That being said, you can try using str.contains(""+char).


Yes, using the indexOf() method on the string class. See the API documentation for this method


  • String.contains() which checks if the string contains a specified sequence of char values
  • String.indexOf() which returns the index within the string of the first occurence of the specified character or substring (there are 4 variations of this method)

you can use this code. It will check the char is present or not. If it is present then the return value is >= 0 otherwise it's -1. Here I am printing alphabets that is not present in the input.

import java.util.Scanner;

public class Test {

public static void letters()
{
    System.out.println("Enter input char");
    Scanner sc = new Scanner(System.in);
    String input = sc.next();
    System.out.println("Output : ");
    for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {
            if(input.toUpperCase().indexOf(alphabet) < 0) 
                System.out.print(alphabet + " ");
    }
}
public static void main(String[] args) {
    letters();
}

}

//Ouput Example
Enter input char
nandu
Output : 
B C E F G H I J K L M O P Q R S T V W X Y Z

static String removeOccurences(String a, String b)
{
    StringBuilder s2 = new StringBuilder(a);

    for(int i=0;i<b.length();i++){
        char ch = b.charAt(i);  
        System.out.println(ch+"  first index"+a.indexOf(ch));

        int lastind = a.lastIndexOf(ch);

    for(int k=new String(s2).indexOf(ch);k > 0;k=new String(s2).indexOf(ch)){
            if(s2.charAt(k) == ch){
                s2.deleteCharAt(k);
        System.out.println("val of s2 :             "+s2.toString());
            }
        }
      }

    System.out.println(s1.toString());

    return (s1.toString());
}

You can use 2 methods from the String class.

  • String.contains() which checks if the string contains a specified sequence of char values
  • String.indexOf() which returns the index within the string of the first occurence of the specified character or substring or returns -1 if the character is not found (there are 4 variations of this method)

Method 1:

String myString = "foobar";
if (myString.contains("x") {
    // Do something.
}

Method 2:

String myString = "foobar";
if (myString.indexOf("x") >= 0 {
    // Do something.
}

Links by: Zach Scrivena


you can use this code. It will check the char is present or not. If it is present then the return value is >= 0 otherwise it's -1. Here I am printing alphabets that is not present in the input.

import java.util.Scanner;

public class Test {

public static void letters()
{
    System.out.println("Enter input char");
    Scanner sc = new Scanner(System.in);
    String input = sc.next();
    System.out.println("Output : ");
    for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {
            if(input.toUpperCase().indexOf(alphabet) < 0) 
                System.out.print(alphabet + " ");
    }
}
public static void main(String[] args) {
    letters();
}

}

//Ouput Example
Enter input char
nandu
Output : 
B C E F G H I J K L M O P Q R S T V W X Y Z

To check if something does not exist in a string, you at least need to look at each character in a string. So even if you don't explicitly use a loop, it'll have the same efficiency. That being said, you can try using str.contains(""+char).


I'm not sure what the original poster is asking exactly. Since indexOf(...) and contains(...) both probably use loops internally, perhaps he's looking to see if this is possible at all without a loop? I can think of two ways off hand, one would of course be recurrsion:

public boolean containsChar(String s, char search) {
    if (s.length() == 0)
        return false;
    else
        return s.charAt(0) == search || containsChar(s.substring(1), search);
}

The other is far less elegant, but completeness...:

/**
 * Works for strings of up to 5 characters
 */
public boolean containsChar(String s, char search) {
    if (s.length() > 5) throw IllegalArgumentException();

    try {
        if (s.charAt(0) == search) return true;
        if (s.charAt(1) == search) return true;
        if (s.charAt(2) == search) return true;
        if (s.charAt(3) == search) return true;
        if (s.charAt(4) == search) return true;
    } catch (IndexOutOfBoundsException e) {
        // this should never happen...
        return false;
    }
    return false;
}

The number of lines grow as you need to support longer and longer strings of course. But there are no loops/recurrsions at all. You can even remove the length check if you're concerned that that length() uses a loop.


Yes, using the indexOf() method on the string class. See the API documentation for this method


If you need to check the same string often you can calculate the character occurrences up-front. This is an implementation that uses a bit array contained into a long array:

public class FastCharacterInStringChecker implements Serializable {
private static final long serialVersionUID = 1L;

private final long[] l = new long[1024]; // 65536 / 64 = 1024

public FastCharacterInStringChecker(final String string) {
    for (final char c: string.toCharArray()) {
        final int index = c >> 6;
        final int value = c - (index << 6);
        l[index] |= 1L << value;
    }
}

public boolean contains(final char c) {
    final int index = c >> 6; // c / 64
    final int value = c - (index << 6); // c - (index * 64)
    return (l[index] & (1L << value)) != 0;
}}

static String removeOccurences(String a, String b)
{
    StringBuilder s2 = new StringBuilder(a);

    for(int i=0;i<b.length();i++){
        char ch = b.charAt(i);  
        System.out.println(ch+"  first index"+a.indexOf(ch));

        int lastind = a.lastIndexOf(ch);

    for(int k=new String(s2).indexOf(ch);k > 0;k=new String(s2).indexOf(ch)){
            if(s2.charAt(k) == ch){
                s2.deleteCharAt(k);
        System.out.println("val of s2 :             "+s2.toString());
            }
        }
      }

    System.out.println(s1.toString());

    return (s1.toString());
}

package com;
public class _index {

    public static void main(String[] args) {
        String s1="be proud to be an indian";
        char ch=s1.charAt(s1.indexOf('e'));
        int count = 0; 
        for(int i=0;i<s1.length();i++) {
            if(s1.charAt(i)=='e'){
                System.out.println("number of E:=="+ch);
                count++;
            }
        }
        System.out.println("Total count of E:=="+count);
    }
}

String.contains(String) or String.indexOf(String) - suggested

"abc".contains("Z"); // false - correct
"zzzz".contains("Z"); // false - correct
"Z".contains("Z"); // true - correct
"and".contains(""); // true - correct
"and".contains(""); // false - correct
"and".indexOf(""); // 0 - correct
"and".indexOf(""); // -1 - correct

String.indexOf(int) and carefully considered String.indexOf(char) with char to int widening

"and".indexOf("".charAt(0)); // 0 though incorrect usage has correct output due to portion of correct data
"and".indexOf("".charAt(0)); // 0 -- incorrect usage and ambiguous result
"and".indexOf("".codePointAt(0)); // -1 -- correct usage and correct output

The discussions around character is ambiguous in Java world

can the value of char or Character considered as single character?

No. In the context of unicode characters, char or Character can sometimes be part of a single character and should not be treated as a complete single character logically.

if not, what should be considered as single character (logically)?

Any system supporting character encodings for Unicode characters should consider unicode's codepoint as single character.

So Java should do that very clear & loud rather than exposing too much of internal implementation details to users.

String class is bad at abstraction (though it requires confusingly good amount of understanding of its encapsulations to understand the abstraction and hence an anti-pattern).

How is it different from general char usage?

char can be only be mapped to a character in Basic Multilingual Plane.

Only codePoint - int can cover the complete range of Unicode characters.

Why is this difference?

char is internally treated as 16-bit unsigned value and could not represent all the unicode characters using UTF-16 internal representation using only 2-bytes. Sometimes, values in a 16-bit range have to be combined with another 16-bit value to correctly define character.

Without getting too verbose, the usage of indexOf, charAt, length and such methods should be more explicit. Sincerely hoping Java will add new UnicodeString and UnicodeCharacter classes with clearly defined abstractions.

Reason to prefer contains and not indexOf(int)

  1. Practically there are many code flows that treat a logical character as char in java.
  2. In Unicode context, char is not sufficient
  3. Though the indexOf takes in an int, char to int conversion masks this from the user and user might do something like str.indexOf(someotherstr.charAt(0))(unless the user is aware of the exact context)
  4. So, treating everything as CharSequence (aka String) is better
    public static void main(String[] args) {
        System.out.println("and".indexOf("".charAt(0))); // 0 though incorrect usage has correct output due to portion of correct data
        System.out.println("and".indexOf("".charAt(0))); // 0 -- incorrect usage and ambiguous result
        System.out.println("and".indexOf("".codePointAt(0))); // -1 -- correct usage and correct output
        System.out.println("and".contains("")); // true - correct
        System.out.println("and".contains("")); // false - correct
    }

To check if something does not exist in a string, you at least need to look at each character in a string. So even if you don't explicitly use a loop, it'll have the same efficiency. That being said, you can try using str.contains(""+char).


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to validation

Rails 2.3.4 Persisting Model on Validation Failure Input type number "only numeric value" validation How can I manually set an Angular form field as invalid? Laravel Password & Password_Confirmation Validation Reactjs - Form input validation Get all validation errors from Angular 2 FormGroup Min / Max Validator in Angular 2 Final How to validate white spaces/empty spaces? [Angular 2] How to Validate on Max File Size in Laravel? WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to character

Set the maximum character length of a UITextField in Swift Max length UITextField Remove last character from string. Swift language Get nth character of a string in Swift programming language How many characters can you store with 1 byte? How to convert integers to characters in C? Converting characters to integers in Java How to check the first character in a string in Bash or UNIX shell? Invisible characters - ASCII How to delete Certain Characters in a excel 2010 cell