Professional Documents
Culture Documents
● Are like local classes except that they cannot have a name.
Syntax:
new Greeting () { /*…class body…*/ }
Parts:
• the name of the interface / base class to implement/extend (in our case the Greeting
interface, which this anonymous class will implement)
• parentheses that contain the arguments to a constructor, just like a normal class
instance creation expression (if there is no constructor, use an empty pair like here)
• class body block - similar to regular classes, may contain fields, methods..
Anonymous classes – Restrictions
Restrictions:
Two types:
- static initializer blocks - executed only once, right after loading the class (happens before
the first actual use)
- instance (non-static) initializer blocks - executed each time a new instance is created, right
before any defined constructors!
class SomeClass {
{
//instance initializer code…
}
static {
//static instance initializer code…
}
}
Class initialization order
//helper method which can be called also for field init For 2nd instance:
static int printAndGet(String text) { instance field init
System.out.println(text); return 1; instance block init
}
}
constructor 1
Class initializers - In anonymous classes
Functional interface = an interface that has only a single abstract method (SAM) (meaning a
single non-implemented method; it may have other implemented ones, like default or static)
Lambda expressions:
- allow to easily create and pass around functions (blocks of code), almost like they were
regular objects! (supporting operations like: store functions in variables, pass them as
parameters to other functions, returning them from functions, applying them later…)
- they add (some) support for functional programming in Java!
Lambda Expressions - Syntax
- If the parameter types can be inferred from the context, they can be omitted:
(param1, param2) -> {
/*statements…*/
return result;
};
Lambda Expressions - Syntax (2)
- If the body of the function consists of only a single statement, the curly braces
and the “return” statement can be omitted:
//DEFINING FUNCTIONS:
//with 1 param:
Function<Integer, Integer> incFunc = i -> i + 1;
Function<Person, Integer> getAge = (Person p) -> p.getAge();
//with 2 params:
BiFunction<Integer, Integer, Integer> maxFunc = (a, b) -> a > b ? a : b;
//APPLYING FUNCTIONS:
int a = 2, b = 3, c = 0;
Person p = new Person(22, 180);
● Lambda expressions which contain only a call to some existing method can be written in
even shorter form, as a method reference
○ Static methods:
(String s) -> Integer.parseInt(s) => Integer::parseInt
○ Constructors:
(String name) -> new Book(name) => Book::new
Streams - The need
List<Artist> artists = …
Iterator<Artist> it = artists.iterator();
long count = 0;
while (it.hasNext()) {
Artist artist = it.next();
if (artist.isFrom("Bern")){
count++;
}
}
Internal Iteration
artists
.stream()
.filter(artist ->
artist.isFrom("Bern"))
.count();
Streams - Definition
- So what is a Stream?
- informally: a fancy iterator with operations
- more formally: a sequence of elements from a source that supports
aggregate operations
● Values:
Stream<String> st = Stream.of("abc", "def");
● Collections:
Collection<String> col = /*…*/ ;
Stream<String> st = col.stream();
● Arrays:
int[] numbers = {2, 3, 5, 7, 11, 13};
IntStream st = Arrays.stream(numbers);
● Iterate:
Stream<Integer> st = Stream.iterate(0, n -> n + 2).limit(10);
● Generate:
Stream<Double> st = Stream.generate(Math::random).limit(5);
Streams Operations
Operations applied to a stream create a pipeline, which is evaluated on 1st terminal op:
Streams - Intermediate Operations
Stream Operations - filter, map
filter() - filters the elements of a stream, keeping the ones fulfilling a given condition
map() - transforms (maps) each element of the stream to another element (of
possibly different type) by applying a given function
List<String> first5words =
streamOfStrings
.filter(s -> s.length() > 1) //filter out short words
.map(String::toLowerCase) //transform to lower
.distinct() //remove duplicates
.sorted() //sort them
.limit(5) //take first 5
.collect(toList()); //terminal op
Streams - Filter
List<String> startingWithDigit =
● collect():
○ accumulates the stream elements into a container
○ requires a parameter which specifies how to accumulate them
■ this parameter is of type Collector
■ many predefined ones, in class java.util.stream.Collectors
● like: collect to a specific type of collection (toList, toSet), to a String
(joining), grouping elements (groupingBy)...
Stream Collectors - Examples
- Compared to Stream, they also have some extra methods: min, max, sum, average
- Benefits:
- shorter, nicer code, more declarative/high level
- Risks:
- dense code, encourages use of anonymous functions
- may lead to cluttered code, hard to read and debug (‘stream-wrecks’)
- Recommendations:
- Write the stream pipeline with each step on a different line
- Prefer using method references
- Keep your lambda expressions short (1 statement); avoid writing “ -> { “, move
instead that block of code to a separate method (with a suggestive name)
- Prefer using the functional interfaces already defined in JDK (instead of inventing/
writing your own)
- Pay attention to order of operations (filter() before map() = more efficient..)
Optional
- Optional<T> - from java.util, is a wrapper over a value (of type T) which may
have only one of two possible states:
- contains a value (T)
- is empty
- also has some unsafe actions, like .get() - it forcefully tries to get the value from the
optional, throws an exception if the optional is actually empty;
- before calling get() you should always check the state with .isPresent()
- OR better yet: use it in a functional / stream-like way! (with map(), orElse()...)
Optional - Example
● https://www.geeksforgeeks.org/instance-initialization-block-iib-java
● http://tutorials.jenkov.com/java/nested-classes.html#anonymous-classes
● http://tutorials.jenkov.com/java/lambda-expressions.html
● http://www.java2s.com/Tutorials/Java_Lambda/Lambda_Tutorial/Lambda/Java_Lambda_
Java_Lambda_Tutorial.htm
● http://tutorials.jenkov.com/java-collections/streams.html
● https://www.baeldung.com/java-inifinite-streams
● https://www.baeldung.com/java-8-primitive-streams
● https://www.baeldung.com/java-optional
● https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples