Skip to main content

Streams and Lambda Syntax

The Aims​

This lab will introduce you to using Streams and Lambda Syntax

Map and filter​

Create a class called Student with properties of name, age and major.

public class Student {
private String name;
private int age;
private String major;

// Constructor, getters, setters, toString, hashcode & equals
}

Create a runnable class that instantiates a list of students, with some suitable values

new Student("Alice", 20, "Computer Science"),
new Student("Bob", 22, "Mathematics"),
new Student("Charlie", 19, "Physics"),
new Student("Diana", 21, "Computer Science"),
new Student("Eve", 23, "Mathematics")
);

Using the map and filter functions of the stream api:

  1. Find all students older than 20

  2. Get a list of all student names in uppercase

  3. Find all Computer Science majors

  4. Get the names of students aged between 20 and 22 (inclusive)

Click here to view the sample solution

// Task 1
List<Student> olderStudents = students.stream()
.filter(s -> s.getAge() > 20)
.collect(Collectors.toList());

// Task 2
List<String> upperNames = students.stream()
.map(Student::getName)
.map(String::toUpperCase)
.collect(Collectors.toList());

// Task 3
List<Student> csStudents = students.stream()
.filter(s -> "Computer Science".equals(s.getMajor()))
.collect(Collectors.toList());

// Task 4
List<String> ageRangeNames = students.stream()
.filter(s -> s.getAge() >= 20 && s.getAge() <= 22)
.map(Student::getName)
.collect(Collectors.toList());

Grouping and statistics​

Create a class called Sale, and a runnable class to instantiate some sale objects, using the following as the basis for your code:

class Sale {
private String product;
private String region;
private double amount;
private LocalDate date;

// Constructor, getters, setters
}

List<Sale> sales = Arrays.asList(
new Sale("Laptop", "North", 1200.0, LocalDate.of(2024, 1, 15)),
new Sale("Phone", "South", 800.0, LocalDate.of(2024, 1, 20)),
new Sale("Laptop", "South", 1300.0, LocalDate.of(2024, 2, 10)),
new Sale("Tablet", "North", 600.0, LocalDate.of(2024, 2, 15)),
new Sale("Phone", "North", 850.0, LocalDate.of(2024, 3, 5))
);

Now write code using streams to:

  1. Calculate total sales amount

  2. Find the highest single sale amount

  3. Group sales by region and calculate total for each

  4. Find all products sold for more than $1000

  5. Calculate average sale amount per product

  6. Find the most recent sale

Click here to view the sample solution

// Task 1
double totalSales = sales.stream()
.mapToDouble(Sale::getAmount)
.sum();

// Task 2
OptionalDouble maxSale = sales.stream()
.mapToDouble(Sale::getAmount)
.max();

// Task 3
Map<String, Double> salesByRegion = sales.stream()
.collect(Collectors.groupingBy(
Sale::getRegion,
Collectors.summingDouble(Sale::getAmount)
));

// Task 4
List<String> expensiveProducts = sales.stream()
.filter(s -> s.getAmount() > 1000)
.map(Sale::getProduct)
.distinct()
.collect(Collectors.toList());

// Task 5
Map<String, Double> avgByProduct = sales.stream()
.collect(Collectors.groupingBy(
Sale::getProduct,
Collectors.averagingDouble(Sale::getAmount)
));

// Task 6
Optional<Sale> mostRecent = sales.stream()
.max(Comparator.comparing(Sale::getDate));

Text Processing​

Create a runnable class to instantiate a list of strings as follows:

List<String> sentences = Arrays.asList(
"Java streams are powerful and flexible",
"Streams make data processing easier",
"Java programming with streams is fun",
"Data processing and manipulation with Java"
);

Now write code that uses flatMap and other transformations to achieve the following:

  1. Given a list of sentences, find all unique words (case-insensitive)

  2. Count the frequency of each word

  3. Find the 5 most common words

  4. Find all words that appear in more than one sentence

Click here to view the sample solution

// Task 1: All unique words
Set<String> uniqueWords = sentences.stream()
.map(String::toLowerCase)
.flatMap(sentence -> Arrays.stream(sentence.split("\\s+")))
.collect(Collectors.toSet());

// Task 2: Word frequency
Map<String, Long> wordFreq = sentences.stream()
.map(String::toLowerCase)
.flatMap(sentence -> Arrays.stream(sentence.split("\\s+")))
.collect(Collectors.groupingBy(
word -> word,
Collectors.counting()
));

// Task 3: Top 5 most common words
List<Map.Entry<String, Long>> top5 = wordFreq.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.limit(5)
.collect(Collectors.toList());

// Task 4: Words in multiple sentences
Set<String> wordsInMultipleSentences = sentences.stream()
.map(String::toLowerCase)
.map(sentence -> new HashSet<>(Arrays.asList(sentence.split("\\s+"))))
.reduce(new HashSet<>(), (acc, words) -> {
Set<String> intersection = new HashSet<>(acc);
intersection.retainAll(words);
acc.addAll(words);
return acc;
});