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 Stream
stream() / parallelStream() creates a stream from the collection
Intermediate operations → lazy, return a Stream
filter() keeps only elements matching a predicate
map() 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
      
→ Execution mode can be modified by the 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
      
→ Predicate - Boolean Values Function → used in filter(...)
→ 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 the BaseStream.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.
  • ✅ Immutable list (cannot be modified)
  • add(), remove(), set() → throw UnsupportedOperationException
  • ❌ 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
    Stream works with objects (wrapper / class types)
  • 👉 Stream<Character>, Stream<Integer>, Stream<String>
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);
      
    Character / String → Stream
  • String (words)
     → Arrays.stream(str.split(",")) : Stream<String>
  • String (characters)str.chars() : IntStream
  • String → Character
     → str.chars().mapToObj(c -> (char) c) : Stream<Character>
     Convert primitive → object using mapToObj()

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 );
      
    Array → Stream
    • Array (Object) → Arrays.stream(arr) : Stream<T>
    • Array (Primitive) → Arrays.stream(intArr) : IntStream
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);
      
    Collection → Stream
    • list.stream() : Stream<T>
    • set.stream() : Stream<T>
    • queue.stream() : Stream<T>
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 → Stream
    • Map (entries) map.entrySet().stream() : Stream<Map.Entry<K,V>>
    • Map (keys) map.keySet().stream() : Stream<K>
    • Map (values) map.values().stream() : Stream<V>
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());
      

⚠️ **GitHub.com Fallback** ⚠️