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:
-
Find all students older than 20
-
Get a list of all student names in uppercase
-
Find all Computer Science majors
-
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:
-
Calculate total sales amount
-
Find the highest single sale amount
-
Group sales by region and calculate total for each
-
Find all products sold for more than $1000
-
Calculate average sale amount per product
-
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:
-
Given a list of sentences, find all unique words (case-insensitive)
-
Count the frequency of each word
-
Find the 5 most common words
-
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;
});