Skip to content

UtkarshYadav01/java-streams-lambdas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

java-streams-lambdas

A revision project covering Java 8+ Streams, Lambdas, and Collectors through interview-focused practice questions.

No Spring Boot. No dependencies. Plain Java only. Run StreamApi.java directly from IntelliJ using Java 25 (supports void main()).


How to Run

Open StreamApi.java in IntelliJ and hit Run. No build step needed — uses Java 25 unnamed class feature (void main()).


Core Concepts

What is a Stream?

A Stream is a sequence of elements that you can process with a pipeline of operations. It does not store data — it processes it from a source (List, Array, Map etc.).

Source → Intermediate Operations → Terminal Operation
  ↓              ↓                        ↓
List         filter, map             collect, forEach
             sorted, limit            reduce, count

Lambda

A shorthand for writing anonymous functions inline.

// without lambda
list.stream().filter(new Predicate<Integer>() {
    public boolean test(Integer n) { return n % 2 == 0; }
});

// with lambda
list.stream().filter(n -> n % 2 == 0);

Method Reference

Even shorter than a lambda when you're just calling an existing method.

// lambda
fruits.stream().map(s -> s.toUpperCase());

// method reference
fruits.stream().map(String::toUpperCase);

Stream Operations

Intermediate (lazy — don't run until terminal is called)

Operation What it does Example
filter Keep elements matching condition .filter(n -> n > 3)
map Transform each element .map(s -> s.toUpperCase())
sorted Sort elements .sorted(Comparator.reverseOrder())
distinct Remove duplicates .distinct()
limit Take first N elements .limit(3)
skip Skip first N elements .skip(1)
flatMap Flatten nested lists into one stream .flatMap(e -> e.skills().stream())
mapToInt Convert to IntStream .mapToInt(Integer::intValue)
mapToDouble Convert to DoubleStream .mapToDouble(i -> i)

Terminal (eager — triggers the pipeline)

Operation What it does Example
forEach Iterate over results .forEach(System.out::println)
collect Gather into collection .collect(Collectors.toList())
count Count elements .count()
reduce Fold elements into one value .reduce(0, Integer::sum)
findFirst Get first match as Optional .findFirst()
min / max Get min or max as Optional .max(Comparator.naturalOrder())
anyMatch True if any element matches .anyMatch(n -> n > 5)
allMatch True if all elements match .allMatch(n -> n > 0)
noneMatch True if no element matches .noneMatch(n -> n < 0)
toArray Collect into array .toArray()

Collectors Reference

// to List, Set, UnmodifiableList
.collect(Collectors.toList())
.collect(Collectors.toSet())
.collect(Collectors.toUnmodifiableList())

// join strings
.collect(Collectors.joining(","))

// count per group
.collect(Collectors.groupingBy(w -> w, Collectors.counting()))

// group into lists
.collect(Collectors.groupingBy(Employees::department))

// group with downstream — avg, sum, min, max
.collect(Collectors.groupingBy(Employees::department, Collectors.averagingDouble(Employees::salary)))
.collect(Collectors.groupingBy(Employees::department, Collectors.summingInt(Employees::salary)))
.collect(Collectors.groupingBy(Employees::department, Collectors.maxBy(Comparator.comparingInt(Employees::salary))))

// nested grouping
.collect(Collectors.groupingBy(e::department, Collectors.groupingBy(e::gender)))

// split into two groups — true / false
.collect(Collectors.partitioningBy(n -> n % 2 == 0))

reduce()

// sum
int sum = list.stream().reduce(0, Integer::sum);

// product
int product = list.stream().reduce(1, (a, b) -> a * b);

// max without Comparator
Optional<Integer> max = list.stream().reduce(Integer::max);

reduce takes an identity value (starting point) and a BinaryOperator. Without identity it returns Optional because the stream might be empty.


Optional

Returned by findFirst, min, max, reduce (without identity). Never call .get() directly — use safe alternatives.

Optional<Integer> result = list.stream().filter(n -> n > 4).findFirst();

result.ifPresent(v -> System.out.println(v));   // only runs if value exists
result.orElse(-1);                               // default if empty
result.orElseThrow();                            // throw if empty
result.isPresent();                              // boolean check

summaryStatistics()

One call gives you count, sum, min, max, average all at once.

IntSummaryStatistics stats = list.stream()
        .mapToInt(Integer::intValue)
        .summaryStatistics();

stats.getCount();
stats.getSum();
stats.getMin();
stats.getMax();
stats.getAverage();

flatMap vs map

// map — one-to-one transformation, stream of lists
employeeSkills.stream()
        .map(e -> e.skills())          // Stream<List<String>>
        .forEach(System.out::println); // prints each list

// flatMap — flatten, stream of individual elements
employeeSkills.stream()
        .flatMap(e -> e.skills().stream())  // Stream<String>
        .forEach(System.out::println);       // prints each skill

Use flatMap whenever you have nested lists and want to process individual elements.


IntStream

// range
IntStream.range(1, 6).forEach(System.out::println);     // 1 2 3 4 5
IntStream.rangeClosed(1, 5).forEach(System.out::println); // 1 2 3 4 5

// merge two int arrays
int[] merged = IntStream.concat(Arrays.stream(arr1), Arrays.stream(arr2))
        .sorted()
        .toArray();

// merge two String/object streams
Stream.concat(list1.stream(), list2.stream())
        .distinct()
        .collect(Collectors.toList());

Interview Questions Covered

# Question Key Operations
01 Second largest number distinct sorted skip limit
02 All even numbers filter
06 Average of list mapToDouble average
09 Find duplicates filter Collections.frequency distinct
10 Square of first 3 even numbers sorted filter limit map
11 Convert strings to uppercase map method reference
12 Concatenate list of strings Collectors.joining
13 Count strings starting with char filter count
14 Remove duplicate words from string Arrays.stream split distinct
15 Word frequency in string groupingBy counting
16 Group names by first letter + count groupingBy charAt counting
17 Merge two int arrays sorted IntStream.concat sorted toArray
18 Concat two lists remove duplicates Stream.concat distinct
19 Filter palindromes filter StringBuilder.reverse
20 Partition even and odd partitioningBy
21 Sort employees by id descending sorted Comparator.comparing
26 Sort Map by key / value entrySet comparingByKey comparingByValue
27 Group employees by department groupingBy
28 Average salary per department groupingBy averagingDouble
29 Sum salary per department groupingBy summingInt
30 Highest/lowest paid per department groupingBy maxBy minBy
31 Group by department then gender nested groupingBy
32 Group strings by length groupingBy String::length
33 Count word occurrences groupingBy counting
34 Reverse each word in sentence map StringBuilder.reverse joining
35 Unique words across paragraphs flatMap distinct
36 Unique skills from employees flatMap distinct toSet
E1 reduce — sum, product, max reduce
E2 Collect to Set / UnmodifiableList toSet toUnmodifiableList
E3 Optional — findFirst, min, max Optional ifPresent orElse
E4 anyMatch / allMatch / noneMatch short-circuit terminal ops
E5 summaryStatistics mapToInt summaryStatistics

Common Mistakes

Mistake Fix
Calling .get() on Optional Use .orElse() or .ifPresent()
Using map when you need flatMap If result is Stream<List<T>> use flatMap
reduce without identity returns Optional Handle it — don't chain directly
Stream already consumed error Create a new stream — can't reuse
sorted() on strings is case-sensitive Use Comparator.comparing(String::toLowerCase)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages