Lambdas are short-forms for functions
Great for tasks that are 1-5 lines long
Helpful to break tasks in to elementary blocks
(a, b) -> {
// CODE here
return abc;
}
Input list
Lambda arrow
Function braces
Raw code
// Notation
(input) -> {
execute(input);
}
// Example
list.forEach((input) -> {
execute(input);
});
// Equivalent Code
for (int i = 0; i < list.size(); i++) {
__consumer_lambda(list.get(i));
}
private void __consumer_lambda(Object input) {
execute(input);
}
// Notation
() -> {
return new Object();
}
// Example
stream.reduce(() -> {
return new Integer(0);
}, (a, b) -> {
return a + b;
});
// Equivalent Code
private Object __supplier_lambda() {
return new Object();
}
// Notation
(a) -> {
return new Person(a);
}
// Example
stream.map((a) -> {
return new Person(a);
});
// Equivalent Code
for (int i = 0; i < ageList.size(); i++) {
int age = ageList.get(i);
Person person = __function_lambda(age);
personList.add(person);
}
private Person __function_lambda(int age) {
return new Person(age);
}
// Notation
(a, b) -> {
return (a + b)/2;
}
// Example
stream.reduce((a, b) -> {
return a + "-" + b;
});
// Equivalent Code
String reduced = list.get(0);
for (int i = 1; i < list.size(); i++) {
reduced = __bifunction_lambda(reduced, list.get(i));
}
private String __bifunction_lambda(String a, String b) {
return a + "-" + b;
}
syntax
{}
::
.x().x()
for chaining(a) -> {
return a - 1;
}
(a) -> a - 1
(a) -> {
return this.func(a);
}
this::func
Stream<?> a = list.stream();
Stream<?> b = a.filter(...);
Stream<?> c = b.map(...);
Stream<?> d = c.distinct();
Stream<?> d = list.stream()
.filter(...)
.map(...)
.distinct();
int[] ages; // This is given from Thomas Gross
int pos;
int temp;
for (int i = 0; i < ages.length; i++) { // Sort ages
pos = i;
for (int j = i+1; j < ages.length; j++) {
if (ages[j] < ages[pos]) {
pos = j;
}
}
temp = ages[pos];
ages[pos] = ages[i];
ages[i] = temp;
}
List<Person> personList = new LinkedList<>();
for (int i = 0; i < ages.length; i++) {
if (ages[i] > 25) { // Exclude by age
personList.add(new Person(ages[i]));
}
}
return personList.get(0); // Return first
min. 28 Points of failure
int[] ages; // This is given from Thomas Gross
return IntStream.of(ages)
.sorted()
.filter(age -> age > 25)
.mapToObj(age -> new Person(age))
.findFirst()
.get();
Sort
Filter by age
Map to person
Retrieve first
7 Points of Failure
(new ArrayList<>()).stream();
(new LinkedList<>()).stream();
(new HashSet<>()).stream();
(new HashMap<>()).entrySet().stream();
(new PriorityQueue<>()).stream();
.stream()
Intermediate
Terminal
.map(Function<A,B>)
.filter(Predicate<A>)
.distinct()
.sorted()
.limit(long)
.flatMap(Function<A,B>)
.reduce(BinaryOperator<T>)
.allMatch(Predicate<T>)
.anyMatch(Predicate<T>)
.forEach(Consumer<T>)
.count()
.collect()
.min()
.max()
Get the unique surnames in uppercase of the first 15 book authors that are 50 y/o or older.
class Book {
Author author;
}
class Author {
String firstname;
String surname;
int age;
}
List<Book> library;
library.stream()
.map(book -> book.getAuthor())
.filter(author -> author.getAge() >= 50)
.map(author -> author.getSurname())
.distinct()
.limit(15)
.map(name -> name.toUpperCase())
.collect(Collectors.toList());
Compute the sum of ages of all female authors younger than 25
class Book {
Author author;
}
class Author {
String firstname;
String surname;
int age;
Gender gender;
}
enum Gender {
MALE, FEMALE;
}
List<Book> library;
library.stream()
.map(book -> book.getAuthor())
.distinct()
.filter(author -> author.getAge() < 25)
.filter(author -> author.getGender() == FEMALE)
.mapToInt(author -> author.getAge())
.sum();
* unless you are really, really, really good
// Accumulate names into a List
List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
// Accumulate names into a TreeSet
Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
// Convert elements to strings and concatenate them, separated by commas
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// Compute sum of salaries of employee
int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary)));
// Group employees by department
Map<Department, List<Employee>> byDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// Compute sum of salaries by department
Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
// Partition students into passing and failing
Map<Boolean, List<Student>> passingFailing =
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
name(Argument) : returnType
filter(Predicate<Integer>) : Steam<Integer>
filter die Daten
das jede Zahl hier true
ergibt
gib uns wieder einen Stream zurück
Crtl + Space
x 2
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
MODULAR DESIGN
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
MODULAR DESIGN
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
MODULAR DESIGN
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
MODULAR DESIGN
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
MODULAR DESIGN
Print the titles of all books that aren't in the library.
Get Titles
Check in library
Get all books
author.authored
library.contains()
book.title
System.out.println()
MODULAR DESIGN
Print the titles of all books that aren't in the library.
class Book {
Author author;
String title;
}
class Author {
String firstname;
String surname;
int age;
List<Book> authored;
}
List<Book> library;
library.stream()
.map(book -> book.author)
.flatMap(author -> author.authored.stream())
.filter(book -> !library.contains(book))
.distinct()
.map(book -> book.title)
.forEach(title -> System.out.println(title));
Hint: flatMap(item -> item.list.stream())
Hint 1: Automate the iteration
Hint 2: Calculate the difference per entry
Hint 1: Collections.reverseOrder()
Hint 2: .limit()
Hint 1: Collectors.toMap()
public class Inspektor {
// Store a reference to all stalls that have previously been scanned
private List<Stall> stalls = new ArrayList<Stall>();
// Store references to stalls that had parasites at some point in time
private Set<Stall> parasiteStalls = new HashSet<Stall>();
public Map<String, String> besteStaelle() {
return stalls.stream()
// Grab a stream of all distinct manufacturer names
.map(stall -> stall.manufacturer)
.distinct()
// Generate pairs (manufacturer, bestStall)
.map(manufacturer -> bestStallPair(manufacturer))
// Remove manufacturers that have no best stall
.filter(p -> p.stallName != null)
// Accumulate all Pairs to a map
.collect(Collectors.toMap(p -> p.manufacturerName, p -> p.stallName));
}
private Pair bestStallPair(String manufacturer) {
String bestStall = stalls.stream()
// Grab a stream of all candidates for this manufacturer
.filter(stall -> !parasiteStalls.contains(stall) && stall.manufacturer.equals(manufacturer))
// Choose the best one
.sorted() // Note that .sorted() requires my custom implementation
.findFirst() // of compareTo(:) in the Stall class!
// Save its name...
.map(stall -> stall.name)
// ... or null if it doesn't exist.
.orElse(null);
return new Pair(manufacturer, bestStall);
}
private static class Stall implements Comparable<Stall> {
String name, manufacturer;
float averageEggs, foodQuantity;
public Stall(String name, float averageEggs, float foodQuantity, String manufacturer) {
this.name = name;
this.averageEggs = averageEggs;
this.foodQuantity = foodQuantity;
this.manufacturer = manufacturer;
}
public Stall(String name) {
this.name = name;
this.averageEggs = 0;
this.foodQuantity = 0;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Stall))
return false;
// Two objects are "identical" if their name is the same!
return name.equals(((Stall) obj).name);
}
@Override
public int hashCode() {
// Two objects are "identical" if their name is the same!
return Objects.hash(name);
}
@Override
public int compareTo(Stall o) {
// Sort in decreasing efficiency
return Float.compare(o.averageEggs / o.foodQuantity, this.averageEggs / this.foodQuantity);
}
}
private static class Pair {
String stallName, manufacturerName;
public Pair(String manufacturerName, String stallName) {
this.stallName = stallName;
this.manufacturerName = manufacturerName;
}
}
}