Definition
- str.chars() returns an
IntStreamof character code points, not aStream. - map(Character::toUpperCase) converts each int code point to uppercase, returning another
IntStream. - mapToObj(c -> String.valueOf((char) c)) boxes the int to a single-character String.
- collect(Collectors.joining()) concatenates all single-character strings into the final result.
- For a list of strings,
list.stream().map(String::toUpperCase).toList()applies uppercase to each element. - In production,
str.toUpperCase()is simpler and faster. The stream approach is typically asked to test knowledge ofchars(),mapToObj, andjoining.
At National Bank of India, customer names captured in mixed case must be normalized to uppercase for the KYC register. The stream approach processes each character individually through a pipeline, like a conveyor belt where each letter passes through an uppercase stamp. In reality, you would just stamp the entire name at once with toUpperCase().
Understanding the Concepts
How do you convert a string to uppercase using streams?
package com.bank.util;
import java.util.List;
import java.util.stream.Collectors;
public class UppercaseStreamDemo {
public static void main(String[] args) {
String input = "neft transfer";
// Character-by-character stream conversion
String upper = input.chars()
.map(Character::toUpperCase)
.mapToObj(c -> String.valueOf((char) c))
.collect(Collectors.joining());
System.out.println(upper);
}
}
NEFT TRANSFER
How do you convert a list of strings to uppercase?
List<String> names = List.of("rajesh", "priya", "amit");
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.toList();
System.out.println(upperNames); // [RAJESH, PRIYA, AMIT]
Why does chars() return IntStream?
Java's chars() method returns IntStream because characters are represented as int code points internally. There is no CharStream in Java. You must use mapToObj to convert back to objects.
// chars() returns IntStream, not Stream<Character>
"abc".chars() // IntStream: [97, 98, 99]
.mapToObj(c -> (char) c) // Stream<Character>: ['a', 'b', 'c']
.toList();
What is the practical approach?
In production code, use str.toUpperCase() directly. The stream approach exists to test your understanding of the chars-mapToObj-joining pipeline.
// Production: just use toUpperCase()
String simple = "neft transfer".toUpperCase(); // NEFT TRANSFER
What about locale sensitivity?
// WRONG for identifiers: locale-dependent
"i".toUpperCase(); // "I" in English, but dotted-I in Turkish locale
// CORRECT for identifiers: locale-independent
"i".toUpperCase(java.util.Locale.ROOT); // always "I"
How is map different from mapToObj?
| Method | Input | Output | Use When |
|--------|-------|--------|----------|
| map on IntStream | int | int | Transforming code points (uppercase) |
| mapToObj on IntStream | int | Object | Converting to String or Character |
| map on Stream | T | R | Transforming objects |
What are common mistakes?
WRONG: Casting IntStream directly to Stream
// WRONG: cannot cast IntStream to Stream<Character>
// input.chars().map(c -> (char) c) // still IntStream!
CORRECT: Use mapToObj to box.
// CORRECT: mapToObj converts IntStream to Stream<Object>
input.chars().mapToObj(c -> (char) c); // Stream<Character>
What should a senior engineer know?
- `String::toUpperCase` is a method reference equivalent to `s -> s.toUpperCase()`. It is an unbound instance method reference. - The stream approach creates many intermediate String objects (one per character). For performance-critical code, use `StringBuilder` or `str.toUpperCase()` directly. - `Character.toUpperCase(int codePoint)` handles supplementary Unicode characters correctly (code points above U+FFFF).
Visual Overview
"neft transfer"
│
▼
chars() → IntStream [110, 101, 102, 116, ...]
│
▼
map(Character::toUpperCase) → IntStream [78, 69, 70, 84, ...]
│
▼
mapToObj(c -> String.valueOf((char) c)) → Stream ["N","E","F","T",...]
│
▼
collect(joining()) → "NEFT TRANSFER"
Key Takeaway
The stream approach for uppercase conversion is chars().map(Character::toUpperCase).mapToObj(c -> String.valueOf((char) c)).collect(joining()). In production, use str.toUpperCase() directly. The stream version is an interview exercise that tests your knowledge of chars() (returns IntStream, not StreammapToObj (boxes int to object), and Collectors.joining() (concatenates strings).
For a list of strings, names.stream().map(String::toUpperCase).toList() is the practical approach. The map operation produces a new list without modifying the source, which matters in banking where original records must stay intact for audit.
Remember one sentence: chars() returns IntStream, mapToObj boxes to objects, and joining concatenates, but in production just use toUpperCase().
---