Back to Stream Practice: Employee Analysis
Q21Question 21 of 43

Find all employees whose name starts with "A"

Key Concepts
  • filter(e -> e.getName().startsWith("A")) keeps only employees whose name begins with the letter A
  • startsWith is case-sensitive: "amit".startsWith("A") returns false
  • For case-insensitive matching, normalize first: name.toUpperCase().startsWith("A")
  • Always guard against null names: e.getName() != null && e.getName().startsWith("A")
  • startsWith(prefix, offset) overload checks a prefix at a given position in the string
  • Parameterize the prefix for reusable code instead of hard-coding the letter

Definition

Filter the stream with a predicate that calls String.startsWith("A") on each employee's name to keep only names beginning with the letter A.
  • String.startsWith(prefix) returns true when the string begins with the given character sequence.
  • filter(e -> e.getName().startsWith("A")) keeps only elements whose name begins with "A".
  • Case sensitivity: startsWith is case-sensitive; "amit" does not start with "A".
  • Null safety: call e.getName() != null before startsWith to avoid NullPointerException.
  • Parameterization: accept the prefix as a method parameter for reusable filtering logic.

The HR clerk at the National Bank of India is told: "Pull the files of everyone whose name begins with A." She flips through the stack of employee ID cards, keeps Amit and Ananya, and puts back Rajesh and Priya. The startsWith("A") method is exactly that first-letter check applied to each card.

Understanding the Concepts

What does this question ask?

The interviewer wants a simple filter operation that uses String.startsWith as the predicate. This tests basic stream filtering and string method knowledge.

How do you filter employees whose name starts with A?

JAVA
package com.bank.hr;

import java.util.*;
import java.util.stream.Collectors;

public class NameStartsWithA {
    public static void main(String[] args) {
        List<Employee> employees = Employee.getSampleEmployees();

        List<Employee> result = employees.stream()
            .filter(e -> e.getName().startsWith("A"))
            .toList();

        result.forEach(e ->
            System.out.println(e.getName() + " (SAV" + e.getAccountId()
                + ") - " + e.getDepartment()));
    }
}
TEXT
Amit (SAV2004) - RISK
Ananya (SAV2009) - COMPLIANCE

The predicate e -> e.getName().startsWith("A") returns true for names beginning with the capital letter A.

Why is startsWith case-sensitive?

startsWith compares characters using their exact values. The capital letter A (Unicode 65) and the lowercase letter a (Unicode 97) are different characters.

JAVA
System.out.println("Amit".startsWith("A"));   // true
System.out.println("amit".startsWith("A"));   // false
System.out.println("AMIT".startsWith("A"));   // true

How do you make it case-insensitive?

Normalize the case before comparing.

JAVA
// Case-insensitive: convert to uppercase first
List<Employee> caseInsensitive = employees.stream()
    .filter(e -> e.getName().toUpperCase().startsWith("A"))
    .toList();

// Alternative: use regionMatches with ignoreCase flag
List<Employee> regionMatch = employees.stream()
    .filter(e -> e.getName().regionMatches(true, 0, "A", 0, 1))
    .toList();

How do you handle null names?

Real banking data often has null or blank names from incomplete records.

JAVA
// WRONG: NullPointerException on null names
List<Employee> wrong = employees.stream()
    .filter(e -> e.getName().startsWith("A"))  // NPE if name is null!
    .toList();

// CORRECT: null guard with short-circuit evaluation
List<Employee> correct = employees.stream()
    .filter(e -> e.getName() != null && e.getName().startsWith("A"))
    .toList();

// CORRECT: using Optional
List<Employee> withOptional = employees.stream()
    .filter(e -> Optional.ofNullable(e.getName())
        .map(n -> n.startsWith("A"))
        .orElse(false))
    .toList();

The null check comes first. Java's short-circuit && operator skips the startsWith call when the name is null.

How do you parameterize the prefix?

JAVA
package com.bank.hr;

import java.util.*;

public class EmployeeFilterService {

    public static List<Employee> filterByNamePrefix(
            List<Employee> employees, String prefix) {
        return employees.stream()
            .filter(e -> e.getName() != null
                && e.getName().toUpperCase()
                    .startsWith(prefix.toUpperCase()))
            .toList();
    }

    public static void main(String[] args) {
        List<Employee> employees = Employee.getSampleEmployees();

        System.out.println("Names starting with 'R':");
        filterByNamePrefix(employees, "R").forEach(e ->
            System.out.println("  " + e.getName()));

        System.out.println("Names starting with 'Pr':");
        filterByNamePrefix(employees, "Pr").forEach(e ->
            System.out.println("  " + e.getName()));
    }
}
TEXT
Names starting with 'R':
  Rajesh
Names starting with 'Pr':
  Priya

How is startsWith different from contains and matches?

| Method | Checks | Example | Result |
|---|---|---|---|
| startsWith("A") | Beginning of string | "Amit".startsWith("A") | true |
| contains("mi") | Anywhere in string | "Amit".contains("mi") | true |
| endsWith("it") | End of string | "Amit".endsWith("it") | true |
| matches("A.*") | Entire string regex | "Amit".matches("A.*") | true |

JAVA
// startsWith: beginning only
List<Employee> prefix = employees.stream()
    .filter(e -> e.getName().startsWith("A")).toList();

// contains: anywhere in the name
List<Employee> anywhere = employees.stream()
    .filter(e -> e.getName().contains("a")).toList();

// matches: full regex pattern
List<Employee> regex = employees.stream()
    .filter(e -> e.getName().matches("[A-D].*")).toList();

What are common mistakes?

Mistake 1: forgetting case sensitivity.

JAVA
// WRONG: misses lowercase names
List<Employee> wrong = employees.stream()
    .filter(e -> e.getName().startsWith("A"))
    .toList();  // misses "amit" if data has lowercase names

// CORRECT: normalize case
List<Employee> correct = employees.stream()
    .filter(e -> e.getName().toUpperCase().startsWith("A"))
    .toList();

Mistake 2: using charAt instead of startsWith for multi-character prefixes.

JAVA
// WRONG for multi-character prefix: charAt only checks one character
boolean wrong = "Priya".charAt(0) == 'P';  // works for single char
boolean alsoWrong = "Priya".charAt(0) == 'P'
    && "Priya".charAt(1) == 'r';  // ugly, error-prone

// CORRECT: startsWith handles any prefix length
boolean correct = "Priya".startsWith("Pr");  // clean and readable

What are common interview follow-up questions?

DIAGRAM
- "How do you filter by the last character instead of the first?" Use `endsWith("a")` instead of `startsWith("A")`.
- "How do you group employees alphabetically by first letter?" Use `groupingBy(e -> e.getName().charAt(0))`.
- "What if you need multiple prefixes?" Create a `Set<String>` of prefixes and check `prefixes.stream().anyMatch(name::startsWith)`.

Visual Overview

DIAGRAM
  Stream<Employee>
  [Rajesh, Priya, Amit, Kavita, Ananya, Suresh, ...]
       │
       │  .filter(e -> e.getName().startsWith("A"))
       ▼
  ┌────────────────────────────────────────────┐
  │  "Rajesh".startsWith("A") → false  ✗ SKIP │
  │  "Priya".startsWith("A")  → false  ✗ SKIP │
  │  "Amit".startsWith("A")   → true   ✓ KEEP │
  │  "Kavita".startsWith("A") → false  ✗ SKIP │
  │  "Ananya".startsWith("A") → true   ✓ KEEP │
  │  "Suresh".startsWith("A") → false  ✗ SKIP │
  └────────────────────────────────────────────┘
       │
       ▼
  [Amit, Ananya]

Key Takeaway

Filtering employees whose name starts with a specific letter uses String.startsWith inside a stream filter predicate. The expression filter(e -> e.getName().startsWith("A")) keeps only employees whose name begins with the capital letter A.

The important detail is that startsWith is case-sensitive. If the data might contain lowercase names, normalize first with toUpperCase(). Real banking data also has null and blank names from incomplete records, so a defensive predicate guards with a null check before calling startsWith, relying on short-circuit evaluation to skip the method call on null.

For production code, parameterize the prefix as a method argument rather than hard-coding the letter A. This lets the same service produce any alphabetical section on demand: pass "R" for Rajesh, "Pr" for Priya, or "SAV" for account codes.

Remember one sentence: filter with startsWith is the simplest stream pattern, but always guard against null names and remember that startsWith is case-sensitive.

---

Share
Use ← → arrow keys to navigate