Java Program to Find the First Non-Repeated Character in a String

Introduction

Finding the first non-repeated character in a String is a common Java programming problem. The goal is to identify the first character that appears exactly once in the given String.

For example, consider the String "swiss". The character 's' appears three times, while 'w' and 'i' appear once. Since 'w' comes before 'i', the first non-repeated character is 'w'.

This problem is frequently asked in Java coding interviews because it tests your understanding of Strings, loops, collections, and character frequency counting. It also helps you practice writing efficient algorithms while preserving the order of characters.

In this tutorial, I will demonstrate how to find the first non-repeated character using LinkedHashMap, nested loops, and Java Streams. I will also explain how to handle Unicode characters and compare the performance of each approach.

1. Understanding the First Non-Repeated Character Problem

Before writing the code, let's understand the expected result.

Consider the following String:

swiss

The characters and their frequencies are:

Character Frequency Repeated?
s 3 Yes
w 1 No
i 1 No

The characters 'w' and 'i' both appear only once.

However, the problem asks for the first non-repeated character. Since 'w' appears before 'i', the expected output is:

First non-repeated character: w

A correct solution must satisfy two conditions:

  1. The character must appear exactly once in the entire String.
  2. It must be the earliest character that satisfies the first condition.

2. Find the First Non-Repeated Character Using LinkedHashMap

Using LinkedHashMap is one of the most efficient and readable ways to solve this problem.

A LinkedHashMap stores key-value pairs and preserves their insertion order by default. For this problem, each character becomes a key, and its frequency becomes the corresponding value.

The program first counts the occurrences of every character. It then checks the entries in insertion order and returns the first character whose frequency is one.

This is especially useful because a regular HashMap does not guarantee iteration order.

Java Program Using LinkedHashMap

import java.util.LinkedHashMap;
import java.util.Map;

public class FirstNonRepeatedCharacter {

    public static void main(String[] args) {

        String input = "swiss";

        Map<Character, Integer> characterCounts = new LinkedHashMap<>();

        // Count the frequency of each character.
        for (char character : input.toCharArray()) {
            characterCounts.merge(character, 1, Integer::sum);
        }

        // Find the first character that appears exactly once.
        Character firstNonRepeated = null;

        for (Map.Entry<Character, Integer> entry : characterCounts.entrySet()) {

            if (entry.getValue() == 1) {
                firstNonRepeated = entry.getKey();
                break;
            }
        }

        if (firstNonRepeated != null) {
            System.out.println(
                    "First non-repeated character: " + firstNonRepeated
            );
        } else {
            System.out.println("No non-repeated character found.");
        }
    }
}

Output

First non-repeated character: w

How Does the Program Work?

Let's understand the important parts of the program.

Step 1: Create a LinkedHashMap

Map<Character, Integer> characterCounts = new LinkedHashMap<>();

The map stores characters as keys and their frequencies as values.

  • Character represents a character in the String.
  • Integer represents how many times that character appears.
  • LinkedHashMap preserves the order in which characters first appear.

Preserving insertion order is important because the program needs to find the first unique character, not just any unique character.

Step 2: Count Character Frequencies

for (char character : input.toCharArray()) {
    characterCounts.merge(character, 1, Integer::sum);
}

The toCharArray() method converts the String into an array of characters.

The enhanced for loop processes each character. The merge() method adds a new character with a count of one or increases its existing count.

For the String "swiss", the map contains:

{s=3, w=1, i=1}

Notice that the characters appear in the order of their first occurrence.

Step 3: Find the First Character with Frequency One

Character firstNonRepeated = null;

for (Map.Entry<Character, Integer> entry : characterCounts.entrySet()) {

    if (entry.getValue() == 1) {
        firstNonRepeated = entry.getKey();
        break;
    }
}

The program iterates through the map entries in insertion order.

When it finds an entry whose frequency equals one, it stores the character in firstNonRepeated.

The break statement immediately stops the loop because the required character has already been found.

Step 4: Display the Result

if (firstNonRepeated != null) {
    System.out.println(
            "First non-repeated character: " + firstNonRepeated
    );
} else {
    System.out.println("No non-repeated character found.");
}

If a unique character exists, the program displays it.

Otherwise, it prints a message indicating that every character appears more than once.

For example, if the input is "aabbcc", the output becomes:

No non-repeated character found.

When should you use this approach?

The LinkedHashMap approach is a good choice for coding interviews and general-purpose character frequency problems. It is easy to explain and has linear average time complexity.

3. Find the First Non-Repeated Character Using Nested Loops

You can also solve this problem using basic for loops without any collections.

The idea is simple. Select one character at a time and count how many times it appears in the entire String. If the frequency is exactly one, that character is the answer.

This approach is useful for beginners because it demonstrates the logic without introducing maps or the Stream API.

Java Program Using For Loops

public class FirstNonRepeatedUsingLoops {

    public static void main(String[] args) {

        String input = "swiss";

        Character firstNonRepeated = null;

        // Check each character from left to right.
        for (int i = 0; i < input.length(); i++) {

            char currentCharacter = input.charAt(i);
            int count = 0;

            // Count occurrences of the current character.
            for (int j = 0; j < input.length(); j++) {

                if (currentCharacter == input.charAt(j)) {
                    count++;
                }
            }

            // The first character with a count of one is the answer.
            if (count == 1) {
                firstNonRepeated = currentCharacter;
                break;
            }
        }

        if (firstNonRepeated != null) {
            System.out.println(
                    "First non-repeated character: " + firstNonRepeated
            );
        } else {
            System.out.println("No non-repeated character found.");
        }
    }
}

Output

First non-repeated character: w

Explanation

The outer loop selects a character from the String:

for (int i = 0; i < input.length(); i++) {
    char currentCharacter = input.charAt(i);
}

The inner loop checks the entire String and counts how often the selected character appears:

for (int j = 0; j < input.length(); j++) {

    if (currentCharacter == input.charAt(j)) {
        count++;
    }
}

For the first character 's', the count is three. Since it is repeated, the program moves to the next character.

The next character is 'w'. Its count is one, so the program stores it and stops searching.

Time Complexity

This approach uses nested loops. In the worst case, it compares each character with every other character.

  • Time complexity: O(n²)
  • Auxiliary space complexity: O(1)

It does not require a map or another collection, but it becomes less efficient as the input grows.

When should you use this approach?

Use nested loops when learning the fundamentals of Java programming or when an interview question specifically asks you to solve the problem without collections.

For larger Strings, the map-based solution is generally more efficient.

4. Find the First Non-Repeated Character Using Java Streams

The Java Stream API provides another approach to finding the first non-repeated character.

In this solution, the program converts the String into a Stream, groups identical characters, counts their occurrences, and finds the first entry whose count is one.

The LinkedHashMap is still important because the solution must preserve the original character order.

Java Program Using Stream API

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FirstNonRepeatedUsingStreams {

    public static void main(String[] args) {

        String input = "swiss";

        // Group characters and count their occurrences.
        Map<Character, Long> characterCounts = input.chars()
                .mapToObj(value -> (char) value)
                .collect(Collectors.groupingBy(
                        Function.identity(),
                        LinkedHashMap::new,
                        Collectors.counting()
                ));

        // Find the first character whose count is one.
        Optional<Character> firstNonRepeated =
                characterCounts.entrySet().stream()
                        .filter(entry -> entry.getValue() == 1)
                        .map(Map.Entry::getKey)
                        .findFirst();

        if (firstNonRepeated.isPresent()) {
            System.out.println(
                    "First non-repeated character: "
                            + firstNonRepeated.get()
            );
        } else {
            System.out.println("No non-repeated character found.");
        }
    }
}

Output

First non-repeated character: w

How Does the Stream API Solution Work?

Step 1: Convert the String into a Stream

input.chars()
        .mapToObj(value -> (char) value)

The chars() method returns an IntStream containing the UTF-16 code units of the String.

The mapToObj() operation converts these values into Character objects.

Step 2: Group and Count Characters

.collect(Collectors.groupingBy(
        Function.identity(),
        LinkedHashMap::new,
        Collectors.counting()
));

The groupingBy() collector creates groups of identical characters.

  • Function.identity() uses each character as its grouping key.
  • LinkedHashMap::new preserves insertion order in this sequential stream.
  • Collectors.counting() calculates the frequency of each character.

The result is a Map<Character, Long>.

Step 3: Find the First Unique Character

Optional<Character> firstNonRepeated =
        characterCounts.entrySet().stream()
                .filter(entry -> entry.getValue() == 1)
                .map(Map.Entry::getKey)
                .findFirst();

The program performs three operations:

  1. filter() selects entries whose frequency is one.
  2. map() extracts the characters from those entries.
  3. findFirst() returns the first matching character.

The result is stored in an Optional<Character> because a non-repeated character may not exist.

This allows the program to handle the absence of a result without using a null value.

When should you use this approach?

This approach is useful when working with the Stream API or practicing functional-style Java programming.

However, for a straightforward coding interview solution, the traditional LinkedHashMap approach is generally easier to explain.

5. Find the First Non-Repeated Unicode Character in Java

Java Strings can contain Unicode characters such as emojis and symbols from different writing systems.

The previous examples use the char type, which represents a single UTF-16 code unit. Some Unicode characters require two UTF-16 code units.

To handle these characters correctly, Java provides the String.codePoints() method.

This method processes Unicode code points rather than individual UTF-16 code units.

Java Program Using Unicode Code Points

import java.util.LinkedHashMap;
import java.util.Map;

public class FirstNonRepeatedUnicodeCharacter {

    public static void main(String[] args) {

        String input = "😀😀🍀a🍀";

        Map<Integer, Integer> characterCounts = new LinkedHashMap<>();

        // Count complete Unicode code points.
        input.codePoints().forEach(codePoint ->
                characterCounts.merge(codePoint, 1, Integer::sum)
        );

        Integer firstNonRepeated = null;

        // Find the first code point that appears once.
        for (Map.Entry<Integer, Integer> entry : characterCounts.entrySet()) {

            if (entry.getValue() == 1) {
                firstNonRepeated = entry.getKey();
                break;
            }
        }

        if (firstNonRepeated != null) {

            // Convert the Unicode code point back into a String.
            String character = new String(
                    Character.toChars(firstNonRepeated)
            );

            System.out.println(
                    "First non-repeated character: " + character
            );
        } else {
            System.out.println("No non-repeated character found.");
        }
    }
}

Output

First non-repeated character: a

Explanation

The String contains two occurrences of the emoji 😀, two occurrences of 🍀, and one occurrence of a.

The program uses:

input.codePoints()

This returns the Unicode code points contained in the String.

The map uses Integer keys because Unicode code points are represented by integer values.

After finding the first code point that occurs once, the program converts it back into a String using:

String character = new String(
        Character.toChars(firstNonRepeated)
);

This is useful when processing text that contains supplementary Unicode characters.

However, some visible symbols contain multiple code points. Examples include certain combined emojis and accented character sequences. Finding the first non-repeated user-perceived character in such text requires grapheme-cluster segmentation rather than code-point counting alone.

6. Handling Different Input Cases

A reliable program should produce sensible results for different inputs.

The following table shows some common test cases for the first LinkedHashMap example.

Input Result Explanation
swiss w First character that appears once
programming p The first character is unique
aabbcc Not found Every character repeats
abc a All characters are unique
aabbc c Only c appears once
Empty String Not found No characters are available

What About Uppercase and Lowercase Characters?

By default, Java treats uppercase and lowercase characters as different values.

For example, the String "aAbB" contains four distinct characters when case sensitivity is enabled.

If your requirements call for case-insensitive matching, normalize the input before processing it:

import java.util.Locale;

String normalizedInput = input.toLowerCase(Locale.ROOT);

For ordinary English text, this allows 'A' and 'a' to be counted together.

Use locale-independent normalization when you want predictable behavior across different system locales. More complex multilingual text may require additional Unicode normalization or case-folding rules.

7. How to Run the Java Programs

You can run these programs using IntelliJ IDEA, Eclipse, VS Code, or the Java command line.

All examples use standard Java APIs. Java 17 or later is sufficient, and no additional libraries are required.

Step 1: Create the Java File

Create a new Java file named FirstNonRepeatedCharacter.java.

Copy the complete LinkedHashMap example into the file.

Step 2: Compile the Program

Open a terminal in the folder containing your Java file and run:

javac FirstNonRepeatedCharacter.java

Step 3: Run the Program

java FirstNonRepeatedCharacter

The program should display:

First non-repeated character: w

To try the other examples, save each program in a separate Java file with the same name as its public class.

8. Comparing Different Approaches

Each approach solves the same problem, but they differ in readability, performance, and memory requirements.

Approach Time Complexity Extra Space Best Use Case
LinkedHashMap O(n) average O(k) General use and coding interviews
Nested Loops O(n²) O(1) Learning basic algorithms
Java Streams O(n) average O(k) Stream API practice
Unicode Code Points O(n) average O(k) Supplementary Unicode characters

Here, n represents the input length, and k represents the number of distinct characters or code points.

The hash-based approaches assume average constant-time map operations.

The nested-loop solution requires no collection, but its quadratic time complexity makes it less suitable for large inputs.

For most Java applications, the LinkedHashMap solution provides a good balance of readability and performance.

9. Common Mistakes to Avoid

1. Using HashMap Without Considering Character Order

A regular HashMap does not guarantee iteration order.

If you iterate through its entries and select the first character with frequency one, you may not get the first non-repeated character from the original String.

Use LinkedHashMap when your algorithm relies on insertion order.

2. Returning the First Character That Appears Once During Counting

A character cannot be considered unique until the entire String has been examined.

For example, the first 'a' in "abca" initially appears once, but it appears again at the end.

Count all occurrences before selecting the first unique character.

3. Ignoring Empty Strings

An empty String contains no characters, so the program should report that no non-repeated character exists.

The map-based example handles this naturally because the map remains empty.

4. Forgetting About Null Input

A null reference is not the same as an empty String.

If you convert this example into a reusable method, decide how to handle null.

For example, you can reject null input:

if (input == null) {
    throw new IllegalArgumentException("Input cannot be null");
}

5. Ignoring Case Sensitivity

Java treats uppercase and lowercase characters as different values. Decide whether 'A' and 'a' should be considered the same before implementing the solution.

6. Assuming Every Unicode Character Fits in a char

The char type represents one UTF-16 code unit, not necessarily a complete Unicode character.

Use String.codePoints() when processing supplementary Unicode characters.

10. Frequently Asked Questions

How do you find the first non-repeated character in a Java String?

Count the occurrences of each character using a LinkedHashMap. Then iterate through its entries and return the first character whose frequency is one.

Why is LinkedHashMap preferred over HashMap?

LinkedHashMap preserves insertion order by default. This is useful because the problem requires the first unique character in the original String.

A regular HashMap does not guarantee iteration order.

Can I find the first non-repeated character without a Map?

Yes. You can use nested loops to count how many times each character appears. This requires constant auxiliary space but takes O(n²) time in the worst case.

Can Java Streams find the first non-repeated character?

Yes. You can use Collectors.groupingBy() with Collectors.counting() to calculate character frequencies. Then filter the entries whose count is one and use findFirst().

What happens if every character is repeated?

If every character appears more than once, there is no non-repeated character.

Your program should handle this case explicitly. You can display a message, return null, or use Optional in a reusable method.

What is the time complexity of finding the first non-repeated character?

Using LinkedHashMap, the average time complexity is O(n), where n is the input length. The nested-loop approach takes O(n²) time in the worst case.

What is the difference between the first unique character and the first non-repeated character?

In this programming problem, both terms usually mean the same thing: the first character in the String that appears exactly once.

Conclusion

In this tutorial, you learned how to find the first non-repeated character in a Java String using LinkedHashMap, nested loops, Java Streams, and Unicode code points.

The LinkedHashMap approach is a practical choice for most applications. It counts character frequencies efficiently and preserves insertion order, which makes it easy to identify the first character that appears only once.

The nested-loop approach helps beginners understand the underlying algorithm, while the Stream API provides an alternative for developers familiar with functional-style programming.

For Strings containing supplementary Unicode characters, String.codePoints() is a better choice than processing individual char values.

As a next step, try modifying the program to find the first repeated character or the first non-repeated word in a sentence. Both problems build on the same frequency-counting concepts and are useful exercises for Java coding interviews.

Continue Learning with Java Guides

Want to take your programming skills to the next level? Explore my practical Udemy courses on Java, Spring Boot, Microservices, Full-Stack Development, Docker, and Generative AI. You can also follow my structured learning roadmaps to become a professional developer.

By Ramesh Fadatare - Udemy Instructor Partner

Comments