Interview Java ‐ JSE - Yash-777/MyWorld GitHub Wiki
In Java, streams are a powerful API introduced in Java 8 that enable functional-style operations on sequences of elements, such as collections or arrays, without modifying the original data source.
- Stream = single processing pipeline, Uses one thread.
- Parallel Stream = multiple pipelines running at the same time using multiple threads (ForkJoinPool). JVM decides the number of threads based on available CPU cores
Stream Pipeline Stages:
Type of Streamstream() / parallelStream()
|
Intermediate operations → lazy, return a Streamfilter() keeps only elements matching a predicatemap() transforms each element |
Terminal operations → trigger execution, return result/value or void collect() gathers the results into a collection |
|---|---|---|
→ Provides data (collection, array, I/O, etc.) to create a stream.
myList // Source
.stream() // Sequential Stream
BaseStream.sequential() or BaseStream.parallel() methods
.stream().parallel()
(or)
.parallelStream().sequential()
|
→ Take the stream of data from the pipeline (lazy - not executed immediately) → Perform intermediate processing (e.g., filter, map) → Return a new stream to the pipeline .filter(n -> n > 10) // Intermediate operation
.map(n -> n * 2) // Intermediate operation
→ Function - function on apply transforms T → R → used in map(...) Predicate greaterThan10 = n -> n > 10;
Function doubleValue = n -> n * 2;
.filter(greaterThan10)
.map(doubleValue)
|
→ Triggers execution → Produces the final result (print, collect, reduce) .forEach(System.out::println);
(or)
.forEach( (e) -> { System.out.println(e); } );
|
- Stream pipelines may execute either sequentially(one thread) or in parallel(multiple threads).
- → Streams are created with an initial choice of sequential or parallel execution.
- For example
-
Collection.stream()creates a sequential stream -
Collection.parallelStream()creates a parallel one.
-
- → This choice of execution mode may be modified by the
BaseStream.sequential() or BaseStream.parallel()methods, and may be queried with theBaseStream.isParallel()method.
Arrays.asList() → Java 5+ |
List.of() → Java 9+ |
|---|---|
// int[] or Integer[]
Integer[] numbersArr = {5, 10, 15, 20, 7, 2}; // {} syntax → array
// Collection
List numbersList =
Arrays.asList(5, 10, 15, 20, 7, 2); // Java 5+ : Arrays.asList() → List
Integer[] numbersListArr = numbersList.toArray( new Integer[0] );
|
List.of() creates an immutable list with fixed elements and does not allow null values.
List immutableList = List.of(5, 10, 15, 20, 7, 2); // Java 9+
immutableList.add(25); // ❌ Runtime exception
//
List mutableList = new ArrayList<>( immutableList );
mutableList.add(25); // ✅ works
|
Stream
|
Example |
|---|---|
Primitives are handled by special streams:
IntStream / LongStream / DoubleStream
Stream<Integer> → for wrapper classes
|
//Primitive values
IntStream ofInt = IntStream.of(1, 2, 3);
IntStream ofChar = IntStream.of('Y', 'a', 's', 'h');
LongStream ofLong = LongStream.of(1L, 2L);
DoubleStream ofDouble = DoubleStream.of(1.0, 2.0);
|
String orElseStr = Optional.ofNullable(str).orElse("");
This avoids NullPointerException cleanly 👍
|
String str = "Yash";
//
// String → IntStream (mapToObj → convert each int to Character) → Stream<Character>
// Stream from char[] (str.toCharArray())
char[] charArray = str.toCharArray();
Stream<Character> stream =
IntStream.range(0, charArray.length)
.mapToObj(i -> charArray[i]);
// Cleaner & recommended (from String directly)
IntStream chars = str.chars();
Stream<Character> streamIntChars = chars.mapToObj(c -> (char) c);
//
// String → Stream (using split)
String[] splitStr = str.split(",");
Stream<String> streamStrSplit = Arrays.stream( splitStr );
|
|
String[] splitStr = str.split(",");
Stream streamStrSplit
= Arrays.stream( splitStr );
//or
= Stream.of( splitStr );
//
int[] numbersArr = {5, 10, 15, 20, 7, 2}; // {} syntax → array
IntStream ofIntArr = Arrays.stream(numbersArr);
|
|
List list = null; // or maybe empty
Collection safeList =
Optional.ofNullable(list).orElse(Collections.emptyList());
safeList.stream().forEach(System.out::println);
//
Set set = null; // or maybe empty
Collection safeSet =
Optional.ofNullable(set).orElse(Collections.emptySet());
safeSet.stream().forEach(System.out::println);
|
Map map = Map.of(
1, "Apple",
2, "Banana",
3, "Cherry"
);
|
//✅ Map entries → Stream>
map.entrySet()
.stream()
.forEach(e ->
System.out.println(e.getKey() + " = " + e.getValue()));
//✅ Map keys → Stream
map.keySet()
.stream()
.forEach(System.out::println);
//✅ Map values → Stream
map.values()
.stream()
.forEach(System.out::println);
|
Given a list of objects, how can you use Java Streams to extract two separate lists of distinct, non-null properties from those objects?
| Combine inside a single stream (recommended) | Combine two lists after collecting |
|---|---|
|
→ flatMap merges them into a single stream → Stream.of(list1, list2) takes both IDs from each participant List combinedIds = participantsList.stream()
.flatMap(p -> Stream.of(p.getTeamLeaderId(), p.getBranchManagerId()))
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
|
→ Stream.concat(list1, list2)
List teamLeaderIds = participantsList.stream()
.map(p -> p.getTeamLeaderId()) // Extract team leader IDs
.filter(Objects::nonNull) // Remove nulls
.distinct() // Remove duplicates
.collect(Collectors.toList());
List branchManagerIds = participantsList.stream()
.filter(p -> p.getBranchManagerId() != null) // Keep only non-null
.map(p -> p.getBranchManagerId()) // Extract branch manager IDs
.distinct() // Remove duplicates
.collect(Collectors.toList());
List combined =
Stream.concat(teamLeaderIds.stream(), branchManagerIds.stream())
.distinct()
.collect(Collectors.toList());
|