DS8 JavaGenrics Java8 Features
DS8 JavaGenrics Java8 Features
Semester 1, 2025/2026
[Link] 2
Early versions of Java lacked generics…
interface Collection {
/** Return true iff the collection contains x */
boolean contains(? x);
/** Add obj to the collection; return true iff
* the collection is changed. */
boolean add(? x);
/** Remove obj from the collection; return true iff
* the collection is changed. */
boolean remove(? x);
...
}
DS – NLU 3
Early versions of Java lacked generics…
interface Collection {
/** Return true iff the collection contains x */
boolean contains(Object x);
/** Add obj to the collection; return true iff
* the collection is changed. */
boolean add(Object x);
/** Remove obj from the collection; return true iff
* the collection is changed. */
boolean remove(Object x);
...
}
DS – NLU 4
Lack of generics was painful because programmers had to
manually cast.
Collection c = ...;
[Link](“Hello”);
[Link](“World”);
//...
for (Object ob : c) {
String s = (String) ob;
[Link]( “[Link]: ”+ [Link]());
}
DS – NLU 5
Limitation seemed especially awkward because built-in arrays
do not have the same problem!
String [] a = ...
a[0] = (“Hello”)
a[1] = (“World”);
//...
For (String s : a) {
[Link](s);
}
DS – NLU 6
One can think of the array “brackets” as a kind of
parameterized type:
◦ a type-level function that takes one type as input and yields another
type as output
Object [] a = ...
String [] b = ...
Integer [] c = ...
Button [] d = ...
DS – NLU 7
With generics, the Collection interface becomes...
Interface Collection<T> {
/** Return true iff the collection contains x */
boolean contains(T x);
/** Add x to the collection; return true iff
*the collection is changed. */
boolean add(T x);
/** Remove x from the collection; return true iff
*the collection is changed. */
boolean remove(T x);
...
}
DS – NLU 8
With generics, no casts are needed...
Collection<String> c = ...;
[Link](“Hello”);
[Link](“World”);
//...
for (String s : c) {
[Link]( “[Link]: ”+ [Link]());
}
DS – NLU 9
Type checking as part of syntax check (compile time)
◦ The compiler can automatically detect uses of collections with incorrect
types...
Collection<String> c= ...
[Link](“Hello”) /* Okay */
[Link](1979); /* Illegal: static error! */
Generally speaking,
Collection<String>
behaves like the parameterized type
Collection<T>
where all occurrences of T have been replaced by String.
DS – NLU 10
Subtyping extends naturally to generic types.
DS – NLU 11
String is a subtype of Object so...
...is LinkedList<String> a subtype of LinkedList<Object>?
DS – NLU 13
An attempt has been made to store the wrong type of object
into an array of objects
Remind
DS – NLU 14
Some comments to below method:
DS – NLU 15
Try replacing Double by some “Type parameter” T, and Java
will still complain that type T is unknown.
T cannot be resolved to a type
/** Replace all values x in list ts by y. */
public void replaceAll(List<Double> ts, Double x, Double
y) { T T T
for (int i = 0; i < [Link](); i = i + 1)
if ([Link]([Link](i), x))
[Link](i, y);
}
DS – NLU 16
Placing <T> after the access modifier indicates that T is to be
considered as a type parameter, to be replaced when method
is called.
DS – NLU 17
Suppose we want to write a method to print every value in a
Collection<T>.
void print(Collection<Object> c) {
for (Object x : c) {
[Link](x);
}
}
...
Collection<Integer> c = ...
[Link](42);
print(c);
DS – NLU 18
To get around this problem, Java’s designers added wildcards
to the language
void print(Collection<?> c) {
for (Object x : c) {
[Link](x);
}
}
...
Collection<Integer> c = ...
[Link](42);
print(c); /* Legal! */
DS – NLU 19
We can’t add values to collections whose types are wildcards
...
void doIt(Collection<?> c) {
[Link](42); /* Illegal! */
}
...
Collection<String> c = ...
doIt(c); /* Legal! */
42 can be added to
• Collection<Integer>
• Collection<Number>
• Collection<Object>
but c could be a Collection of anything, not just
supertypes of Integer
DS – NLU 20
Sometimes it is useful to have some information about a
wildcard. Can do this by adding bounds...
DS – NLU 21
“? extends” is useful for when you are only receiving values
from the object, such as getting values out of a Collection.
DS – NLU 22
Wildcards can be nested. The following receives Collections from an
Iterable and then gives floats to those Collections.
DS – NLU 23
Generics in Java is one of important feature added in Java 5 along
with Enum, autoboxing and varargs, to provide compile time type-
safety.
bounded wildcards:
<? extends T>: all Types must be sub-class of T . T represents the upper
bound
<? super T>: all Types required to be the superclass of T. T represents the
lower bound.
unbounded wildcard:
<?>: any type, similar to Object in Java
DS – NLU 24
Here’s the printing example again. Written with a method type-
parameter.
<T> void print(Collection<T> c){//T is a type
parameter
for(T x : c){
[Link](x);
}
}
...
Collection<Integer> c=...
[Link](42);
print(c);/*More explicitly:this.<Integer> print(c)*/
DS – NLU 25
Interface Comparable<T> declares a method for comparing
one object to another.
interface Comparable<T>{
/*Return a negative number,0,or positive
number
*depending on whether this is less than,
*equal to,or greater than that*/
int compareTo(T that);
}
DS – NLU 26
Type parameter: anything T that implements Comparable<T>
DS – NLU 27
Autoboxing is the automatic conversion that the Java compiler
makes between the primitive types and their corresponding object
wrapper classes.
DS – NLU 28
Consider the following code:
DS – NLU 29
The Java compiler applies autoboxing when a primitive value
is:
DS – NLU 30
Converting an object of a wrapper type (Integer) to its
corresponding primitive (int) value.
DS – NLU 31
DS – NLU 32
Autoboxing and unboxing lets developers write cleaner code,
making it easier to read.
DS – NLU 33
A feature that simplifies the creation of methods that need to
take a variable number of arguments.
DS – NLU 34
Syntax of varargs:
DS – NLU 35
Example:
DS – NLU 36
DS – NLU 37
Varargs are straight forward to use. But there're a few rules we
have to keep in mind:
DS – NLU 38
39
Representing a group of named constants in a programming
language.
Declaration of enum in java:
◦ Enum declaration can be done outside a Class or inside a Class but not
inside a Method.
◦ It is recommended that we name constant with all capital letters
DS – NLU 40
Every enum internally implemented by using Class.
DS – NLU 41
Every enum constant represents an object of type enum.
DS – NLU 42
Enum in switch
… case
DS – NLU 43
Every enum constant is always implicitly public static final.
➔ access it by using enum Name because of static.
➔ can’t create child enums because of final.
We can declare main() method inside enum.
DS – NLU 44
All enums implicitly extend [Link] class.
➔an enum cannot extend anything else.
DS – NLU 45
DS – NLU 46
values() method can be used to return all values present
inside enum.
DS – NLU 47
DS – NLU 48
enum and constructor:
◦ enum can contain constructor and it is executed separately for each
enum constant at the time of enum class loading.
◦ We can’t create enum objects explicitly and hence we can’t invoke
enum constructor directly.
DS – NLU 49
DS – NLU 50
51
52
Interfaces in Java 8 can now declare methods with
implementation code
DS – NLU 53
Java 8 just added several methods to Collection interfaces
DS – NLU 54
Default methods in interface provide implementation, if it is not provided
by the class.
◦ Overriding is OK.
Static methods in interface provide implementation that can be used in
default methods (or elsewhere).
◦ Overriding is not OK.
Methods defined in class are always „stronger“ than
methods defined in interface.
If a class implements two (or more) interfaces that have the same
method, it is up to the class to decide about implementation of this
method.
DS – NLU 55
A Java 8 interface may include a method marked as default (not static and
has a body)
DS – NLU 56
Syntax:
DS – NLU 57
There is a possibility that a class is implementing two
interfaces with same default methods
DS – NLU 58
First solution is to create an own method that overrides the
default implementation.
DS – NLU 59
DS – NLU 60
DS – NLU 61
DS – NLU 62
Semantics: (possible not override)
DS – NLU 63
Static Methods in Interface:
DS – NLU 64
DS – NLU 65
66
Interface Abstract class
Constructors
Static fields
Non static fields
Final fields
Non-final fields
Private fields/methods
Protected fields/methods
Public fields/methods
Abstract methods
Static methods
Final methods
Non-final methods
Default methods DS – NLU 67
Interface Abstract class
Constructors
Static fields
Non static fields
Final fields
Non-final fields
Private fields/methods
(private methods Java9)
Protected fields/methods
Public fields/methods
Abstract methods
Static methods
Final methods
Non-final methods
Default methods DS – NLU
68
69
Functional programming is a programming paradigm where
programs are constructed by applying and composing
functions.
The functional style of programming was introduced in Java 8.
The basic concepts are:
◦ Functional interfaces
◦ Method reference expressions
◦ Lambda expressions
◦ Streams
◦ Collectors (not Collections)
DS – NLU 70
Functional programming could be considered as pure
functions:
◦ input-output only
◦ no side-effects
a function relies on, or modifies, something outside its parameters to do
something
DS – NLU 71
72
An Interface that contains exactly one abstract method.
◦ It can have any number of default, static methods but can contain only
one abstract method. It can also declare methods of object class.
DS – NLU 73
Functional interface Sayable with single method named
say(String msg)
DS – NLU 74
Consumer<T> is an inbuilt functional interface introduced in
java 8 ([Link])
Can be used with a lambda expression and method reference
DS – NLU 75
Consumer instance called multiplier of Integer type.
◦ Multiplier operates on an Integer parameter.
The accept method simply multiplies the input number by
itself and prints the result
Output
100
16
DS – NLU 76
Predicate<T> is an inbuilt functional interface introduced in
java 8 ([Link])
Can be used with a lambda expression and method reference
DS – NLU 77
Predicate instance called stringChecker of String type.
◦ stringChecker accepts an argument of type String.
The test method invokes the isEmpty method on the input
String and a boolean value accordingly.
Output
Hello is empty:false
DS – NLU 78
Supplier<T> is an inbuilt functional interface introduced in
java 8 ([Link])
Can be used with lambda expression and method reference
DS – NLU 79
Supplier instance called randomNumberSupplier of Double
type.
◦ randomNumberSupplier returns a result of type Double
The get method simply returns a new Random Double
number.
Output
0.7304302967434272
0.7304302967434272
DS – NLU 80
Function<T,R> is an inbuilt functional interface introduced in
java 8 ([Link])
Can be used with a lambda expression and method reference
DS – NLU 81
Function instance called yearRetriever.
◦ It accepts an argument of type LocalDate and returns a result of type
Integer.
The apply method accepts a LocalDate object and returns the
year component corresponding to the LocalDate.
Output
Year corresponding to 2021-11-29 is 2021
DS – NLU 82
DS – NLU 83
DS – NLU 84
DS – NLU 85
DS – NLU 86
DS – NLU 87
88
Term comes from λ-Calculus
◦ Everything is a function!
◦ Church-TuringThesis, ~1934
DS – NLU 89
DS – NLU 90
DS – NLU 91
DS – NLU 92
They feel like lambdas, and they’re called lambdas
◦ But they’re no more anonymous than 1.1 CICE’s!
◦ Method has name, class does not*
◦ But method name does not appear in code
DS – NLU 93
Interfaces with only one explicit abstract method
◦ AKA SAM interface (Single Abstract Method)
Optionally annotated with @FunctionalInterface
◦ Do it, for the same reason you use @Override
Some functional interfaces you know
◦ [Link]
◦ [Link]
◦ [Link]
◦ [Link]
◦ Many, many more in package [Link]
DS – NLU 94
Lambda expressions are added in Java 8 and provide below
functionalities.
◦ Enable to treat functionality as a method argument, or code as data.
DS – NLU 95
Java lambda expression is consisted of three components.
◦ 1) Argument-list: It can be empty or non-empty as well.
◦ 2) Arrow-token: It is used to link arguments-list and body of
expression.
◦ 3) Body: It contains expressions and statements for lambda
expression.
DS – NLU 96
DS – NLU 97
DS – NLU 98
DS – NLU 99
DS – NLU 100
DS – NLU 101
DS – NLU 102
If there is only one statement ➔ may or may not use return keyword.
DS – NLU 103
Multiple statements ➔ must use return keyword.
DS – NLU 104
DS – NLU 105
DS – NLU 106
DS – NLU 107
DS – NLU 108
DS – NLU 109
110
A concise notation for certain lambdas
◦ lambda expression:
[Link](a -> [Link]());
◦ method reference:
[Link](Account::addInterest);
DS – NLU 111
4 types of method references:
◦ Static method reference
◦ Constructor reference
DS – NLU 112
Various forms of method references ...
◦ static method: Type::MethodName
e.g. System::currentTimeMillis
◦ constructor: Type::new
e.g. String::new
DS – NLU 113
Various forms of method references ...
◦ non-static method w/ unbound receiver: Type::MethodName
e.g. String::length
DS – NLU 114
Situation:
called: receiver
Two possibilities:
DS – NLU 115
Calling a method in a lambda to an external object that
already exists
Syntax: bounded
receiver since
the receiver is
instance"::"methodName bounded to the
instance
(instance: represents any object instance)
DS – NLU 116
Referring to a method of an object that will be supplied as
one of the lambda’s parameters
unbouned
Syntax: receiver since
the receiver is
bounded later
Type "::"MethodName
Example:
(Type: represents any object instance)
[Link](
(String s1, String s2) -> [Link](s2));
DS – NLU 117
Example 1:
Stream<Person> psp = ... ;
[Link](Person::compareByName);
class Person {
public static int compareByName(Person a, Person b) { … }
}
Example 2:
Stream<String> stringStream = ... ;
[Link](String::compareToIgnoreCase);
class String {
public int compareToIgnoreClase(String str) { … }
}
DS – NLU 118
Situations for three different ways of method reference:
◦ (args) -> [Link](args) can be
ClassName::staticMethod
This is static (you can think as unBound also)
DS – NLU 120
DS – NLU 121
122
A bunch of data objects, typically from a collection,
array, or input device, for bulk data processing
Processed by a pipeline
◦ A single stream generator (data source)
◦ Zero or more intermediate stream operations
◦ A single terminal stream operation
Supports mostly-functional data processing
Enables painless parallelism
◦ Simply replace stream with parallelStream
◦ We may or may not see a performance improvement
DS – NLU 123
Components of a stream pipeline
DS – NLU 124
interface [Link]<T>
◦ Consists of classes, interfaces and enum to allows functional-style
operations on the elements
◦ Supports forEach, filter, map, reduce, and more
Two new methods in [Link]<T>
◦ Stream<T> stream(), sequential functionality
◦ Stream<T> parallelStream(), parallel functionality
DS – NLU 125
Stream does not store elements.
◦ It simply conveys elements from a source such as a data structure, an array,
or an I/O channel, through a pipeline of computational operations.
DS – NLU 128
Actually applied functionality is two-folded
◦ user-defined: functionality passed as parameter
◦ framework method: stream operations
DS – NLU 131
Build a new sequence, where each element is the result of a
mapping from an element of the original sequence
◦ An intermediate operation that consumes a stream and produces a
stream
DS – NLU 132
Returns a stream that replaces each stream element
w/contents of a mapped stream produced by applying the
provided mapping function to each element.
DS – NLU 134
Produce a single result from all elements of the sequence
◦ A terminal operation that consumes a stream and produces a single
result and not a stream.
Example: Concatenate all fruits that start with “A”.
DS – NLU 135
Determine whether any elements of this stream match the provided
predicate
boolean anyMatch(Predicate<? super T> predicate)
Parameters:
◦ predicate - a non-interfering, stateless predicate to apply to elements
of this stream
Returns:
◦ true if any elements of the stream match the provided predicate,
otherwise false
DS – NLU 136
Determine whether any elements of this stream match the provided
predicate
boolean anyMatch(Predicate<? super T> predicate)
DS – NLU 137
Returns true if all the elements of the stream match the
provided predicate condition.
◦ If even one of the elements does not match the predicate condition ➔
skips the testing of the remaining elements
boolean allMatch(Predicate<? super T> predicate)
DS – NLU 138
Returns true if none of the elements of the stream match the
provided predicate condition.
◦ If one (or more) of the elements match the predicate condition ➔
returns false.
boolean noneMatch(Predicate<? super T> predicate)
DS – NLU 139
Count the number of elements in a Stream.
◦ It is terminal operation.
long count();
Usage:
DS – NLU 140
An intermediate operation that returns a stream not longer
than the requested size.
Stream<T> limit(long N)
Usage:
DS – NLU 141
Returns a stream consisting of the remaining elements of this
stream after discarding the first n elements of the stream.
◦ If this stream contains fewer than n elements then an empty stream
will be returned.
Stream<T> skip(long n)
Usage:
DS – NLU 142
Streams provide support for parallel computation to exploit
multiple cores on a processing unit.
◦ by creating a stream().parallel() or any [Link]()
Example: Find fruits, whose names end with “e” using a
parallel stream.
DS – NLU 143
Streams for elements with primitive type:
◦ IntStream, LongStream, DoubleStream
Reason: performance
◦ code optimization; no buffering of intermediate stream results; easier to
handle parallel streams
DS – NLU 144
[Link]<T>
◦ Stream<T> stream(), sequential functionality
◦ Stream<T> parallelStream(), parallel functionality
[Link]
◦ static <T> Stream<T> stream(T[] array)
◦ plus overloaded versions (primitive types, ...)
many more ...
Collections allow to obtain a parallel stream directly
◦ in all other cases use stream’s method: parallel()
DS – NLU 145
Collections Streams
Collections are mainly used to Streams are mainly used to
store and group the data. perform operations on data.
You can add or remove elements You can’t add or remove elements
from collections. from streams.
Collections have to be iterated Streams are internally iterated.
externally.
Collections can be traversed Streams are traversable only once.
multiple times.
Collections are eagerly Streams are lazily constructed.
constructed.
DS – NLU 146
Collections: used to store and group the data in a particular data
structure like List, Set or Map.
Streams: used to perform complex data processing operations like
filtering, matching, mapping, etc. on stored data such as arrays,
collections or I/O resources.
Output:
Charlie
Douglas
Sundaraman
Yuki
DS – NLU 147
We can add to or remove elements from collections.
But, we can’t add to or remove elements from streams.
◦ Stream consumes a source, performs operations on it and returns a
result.
DS – NLU 148
Streams perform iteration internally (collections are externally
iterated)
DS – NLU 149
Streams are traversable only once.
◦ To traverse it again, you have to get new stream from the source again.
But, collections can be traversed multiple times.
DS – NLU 150
Collections are eagerly constructed
◦ i.e all the elements are computed at the beginning itself.
But, streams are lazily constructed
◦ i.e intermediate operations are not evaluated until terminal operation is
invoked
DS – NLU 151
152
Group a list of transactions by currency to obtain the sum of the values
of all transactions with that
currency
◦ returning a Map<Currency, Integer>
DS – NLU 153
[Link](): one of the Java 8's Stream API‘s terminal
methods.
◦ perform mutable fold operations (repackaging elements to some data
structures and applying some additional logic, concatenating them,
etc.) on data elements held in a Stream instance.
DS – NLU 154
Collectors is a final utility class that extends Object class.
It provides reduction operations which are used with terminal
operation [Link]():
◦ accumulating elements into collections,
◦ summarizing elements according to various criteria, etc.
DS – NLU 155
[Link]() [Link]/Long
/Int()
[Link]()
[Link]/Long
[Link]()
/Int()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]/L
[Link]()
ong/Int()
…
DS – NLU 156
Collects the elements of a stream into a new List.
DS – NLU 157
Collects the elements of a stream into a new List.
DS – NLU 158
Used for collecting all Stream elements into a List instance..
DS – NLU 159
immutable list
DS – NLU 160
Java 9:
DS – NLU 161
Used for collecting all Stream elements into a List instance
DS – NLU 162
To access static members, it is necessary to qualify references
with the class they came from.
DS – NLU 164
[Link]():
◦ can accept desired constructor method reference like ArrayList::new,
LinkedList::new, HashSet::new, …
DS – NLU 165
Also use the toCollection() method to add elements of a
stream to an existing list (or a set)
DS – NLU 166
Map collector can be used to collect Stream elements into a
Map instance.
public static <T,K,U> Collector<T,?,Map<K,U>>
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper)
Two functions:
◦ keyMapper: extract a Map key from a Stream element
◦ valueMapper: extract a value associated with a given key
DS – NLU 167
public static <T,K,U> Collector<T,?,Map<K,U>>
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper)
Type parameters:
◦ T - the type of the input elements
◦ K - the output type of the key mapping function
◦ U - the output type of the value mapping function
Returns:
◦ a Collector which collects elements into a Map whose keys and values
are the result of applying mapping functions to the input elements
DS – NLU 168
public static <T,K,U> Collector<T,?,Map<K,U>>
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper)
DS – NLU 169
How about this code fragment?
DS – NLU 170
public static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<?
super T,? extends K> keyMapper, Function<? super T,? extends U>
valueMapper, BinaryOperator<U> mergeFunction)
Parameters:
◦ mergeFunction - a merge function, used to resolve collisions between values
associated with the same key, as supplied to [Link](Object, Object,
BiFunction)
Returns:
◦ a Collector which collects elements into a Map whose keys are the result of
applying a key mapping function to the input elements, and whose values are
the result of applying a value mapping function to all input elements equal to
the key and combining them using the merge function
DS – NLU 171
Solution to the code fragment:
DS – NLU 172
public static <T,K,U,M extends Map<K,U>> Collector<T,?,M>
toMap(Function<? super T,? extends K> keyMapper, Function<? super
T,? extends U> valueMapper, BinaryOperator<U> mergeFunction,
Supplier<M>mapSupplier)
Type parameters:
◦ M - the type of the resulting Map
Parameters:
◦ mapSupplier - a function which returns a new, empty Map into which the results
will be inserted
Returns:
◦ a Collector which collects elements into a Map whose keys are the result of
applying a key mapping function to the input elements, and whose values are the
result of applying a value mapping function to all input elements equal to the key
and combining them using the merge function
DS – NLU 173
Adapts a Collector accepting elements of type U to one
accepting elements of type T by applying a mapping function
to each input element before accumulation.
public static <T,U,A,R> Collector<T,?,R> mapping(Function<?
super T,? extends U> mapper, Collector<? super U,A,R>
downstream)
Type Parameters:
◦ T - the type of the input elements
◦ U - type of elements accepted by downstream collector
◦ A - intermediate accumulation type of the downstream collector
◦ R - result type of collector
DS – NLU 174
public static <T,U,A,R> Collector<T,?,R> mapping(Function<?
super T,? extends U> mapper, Collector<? super U,A,R>
downstream)
Parameters:
◦ mapper - a function to be applied to the input elements
◦ downstream - a collector which will accept mapped values
Returns:
◦ a collector which applies the mapping function to the input elements
and provides the mapped results to the downstream collector
DS – NLU 175
public static <T,U,A,R> Collector<T,?,R> mapping(Function<?
super T,? extends U> mapper, Collector<? super U,A,R>
downstream)
DS – NLU 176
Counting is a simple collector that allows simply counting of
all Stream elements.
DS – NLU 177
public static <T,K> Collector<T,?,Map<K,List<T>>>
groupingBy(Function<? super T,? extends K> classifier)
Type Parameters:
◦ T - the type of the input elements
◦ K - the type of the keys
Parameters:
◦ classifier - the classifier function mapping input elements to keys
Returns:
◦ a Collector implementing the group-by operation
DS – NLU 178
GroupingBy collector is used for grouping objects by some
property and storing results in a Map instance.
DS – NLU 179
public static <T,K,A,D> Collector<T,?,Map<K,D>>
groupingBy(Function<? super T,? extends K> classifier,
Collector<? super T,A,D> downstream)
Type Parameters:
◦ T - the type of the input elements
◦ K - the type of the keys
◦ A - the intermediate accumulation type of the downstream collector
◦ D - the result type of the downstream reduction
◦ M - the type of the resulting Map
DS – NLU 180
public static <T,K,A,D> Collector<T,?,Map<K,D>>
groupingBy(Function<? super T,? extends K> classifier,
Collector<? super T,A,D> downstream)
Parameters:
◦ classifier - the classifier function mapping input elements to keys
◦ downstream - a Collector implementing the downstream reduction
Returns:
◦ a Collector implementing the group-by operation
DS – NLU 181
public static <T,K,A,D> Collector<T,?,Map<K,D>>
groupingBy(Function<? super T,? extends K> classifier,
Collector<? super T,A,D> downstream)
DS – NLU 182
public static <T,K,D,A,M extends Map<K,D>>
Collector<T,?,M> groupingBy(Function<? super T,? extends K>
classifier, Supplier<M> mapFactory, Collector<? super T,A,D>
downstream)
Type Parameters:
◦ T - the type of the input elements
◦ K - the type of the keys
◦ A - the intermediate accumulation type of the downstream collector
◦ D - the result type of the downstream reduction
◦ M - the type of the resulting Map
DS – NLU 183
public static <T,K,D,A,M extends Map<K,D>>
Collector<T,?,M> groupingBy(Function<? super T,? extends K>
classifier, Supplier<M> mapFactory, Collector<? super T,A,D>
downstream)
Parameters:
◦ classifier - the classifier function mapping input elements to keys
◦ mapFactory - a function which, when called, produces a new empty
Map of the desired type
◦ downstream - a Collector implementing the downstream reduction
Returns:
◦ a Collector implementing the group-by operation
DS – NLU 184
public static <T,K,D,A,M extends Map<K,D>>
Collector<T,?,M> groupingBy(Function<? super T,? extends
K> classifier, Supplier<M> mapFactory, Collector<? super
T,A,D> downstream)
DS – NLU 185
PartitioningBy is a specialized case of groupingBy
◦ accepts a Predicate instance
◦ and collects Stream elements into a Map instance
◦ that stores Boolean values as keys and collections as values.
DS – NLU 186
These methods return a collector that outputs the
minimum/maximum element according to the provided
comparator.
DS – NLU 187
Adopts Collector so that we can perform an additional
finishing transformation
public static <T, A, R, RR> Collector <T, A, RR>
collectingAndThen(Collector <T, A, R> downstream, Function
<R, RR> finisher)
Type Parameters:
◦ T - The type of the input elements
◦ A - Intermediate accumulation type of the downstream collector
◦ R - Result type of the downstream collector
◦ RR - Result type of the resulting collector
DS – NLU 188
public static <T, A, R, RR> Collector <T, A, RR>
collectingAndThen(Collector <T, A, R> downstream, Function
<R, RR> finisher)
Parameters:
◦ downstream - a collector
◦ finisher - a function to be applied to the final result of the downstream
collector
Returns:
◦ a collector which performs the action of the downstream collector,
followed by an additional finishing step
DS – NLU 189
public static <T, A, R, RR> Collector <T, A, RR>
collectingAndThen(Collector <T, A, R> downstream, Function
<R, RR> finisher)
Usage:
DS – NLU 190
public final class Optional<T> extends Object
DS – NLU 191
DS – NLU 192
orElse() vs orElseGet()
DS – NLU 193
used to group all elements to a string.
◦ returns one collector that joins all elements to a string.
one-two-three-four-five
DS – NLU 194
195
A new, concise and interesting way to iterate over a collection.
◦ can be used to loop or iterate a Map, List, Set, or Stream.
DS – NLU 196
DS – NLU 197
DS – NLU 198
DS – NLU 199
For sequential streams, the order of elements (during
iteration) is same as the order in the stream source.
While using parallel streams:
◦ forEach() method does not gaurantee the element ordering to provide
the advantages of parallelism.
◦ use forEachOrdered() if order of the elements matter during the
iteration
DS – NLU 200
201
Java provides a new additional feature in Array class which is
used to sort array elements parallel.
DS – NLU 202
Some selected methods:
DS – NLU 203
Example:
DS – NLU 204
205
Java 8 introduced new APIs for Date and Time to address the
shortcomings of the older [Link] and
[Link].
Issues With the Existing Date/Time APIs:
◦ Thread safety – The Date and Calendar classes are not thread safe.
◦ API design and ease of understanding – The Date and Calendar APIs are
poorly designed with inadequate methods to perform day-to-day
operations.
◦ ZonedDate and Time – Developers had to write additional logic to handle
time-zone logic
DS – NLU 206
Java 8 introduced the [Link] package including:
◦ LocalDate,
◦ LocalTime,
◦ LocalDateTime,
◦ ZonedDateTime,
◦ Period,
◦ Duration
◦ and their supported APIs.
DS – NLU 207
The LocalDate represents a date in ISO format (yyyy-MM-dd)
without time.
DS – NLU 208
Gets the current local date and adds one day:
LocalDate tomorrow = [Link]().plusDays(1);
Others:
DS – NLU 209
The LocalTime represents time without a date.
An instance of current LocalTime:
LocalTime now = [Link]();
A LocalTime representing 6:30 a.m. by parsing a string
representation:
LocalTime sixThirty = [Link]("06:30");
A LocalTime representing 6:30 a.m. using the factory method:
LocalTime sixThirty = [Link](6, 30);
DS – NLU 210
Others:
DS – NLU 211
LocalDateTime is used to represent a combination of date and
time.
An instance of LocalDateTime:
[Link]();
Others:
DS – NLU 212
ZonedDateTime: deal with time-zone-specific date and time
DS – NLU 213
Others:
DS – NLU 214
The Period class represents a quantity of time in terms of
years, months and days
2024-12-20, 2024-12-25, 5, 5
DS – NLU 215
Similar to Period, the Duration class is used to deal with Time
DS – NLU 216
Java 8 has added the toInstant() method, which helps to
convert existing Date and Calendar instances to new Date and
Time API
[Link]([Link](),
[Link]());
[Link]([Link](),
[Link]());
DS – NLU 217
Java 8 provides APIs for the easy formatting of Date and Time:
DS – NLU 218
Nashorn – the new default JavaScript engine for the JVM as of
Java 8
A command line interpreter called jjs which can be used to
run JavaScript files
DS – NLU 219
A more common way to run JavaScript from within the JVM is via
the ScriptEngine
[Link]
[Link]#GUID-0C8FD2AD-6000-425F-BC22-
25AAC6A14225
DS – NLU 220
221
In Java 9, private methods can be added to interfaces in Java
Private methods can be implemented static or non-static
◦ ➔ private methods to encapsulate code from both default and static
public method
Interfaces are able to use private methods to hide details on
implementation from classes that implement the interface.
◦ ➔ The main benefit of having these in interfaces is encapsulation
DS – NLU 222
Usage:
DS – NLU 223
224
Declaring multi-line strings using:
◦ concatenation,
◦ String’s join method,
◦ StringBuilder append method,
◦ etc.
DS – NLU 225
A text block is an alternative form of Java string
representation that can be used anywhere a traditional double
quoted string literal can be used
DS – NLU 226
The object produced from a text block is a [Link]
with the same characteristics as a traditional double quoted
string
DS – NLU 227
Text blocks can be used anywhere a string literal can be
used
DS – NLU 228
Text blocks may be used as a method argument:
DS – NLU 229
A text block can be used in place of a string literal to improve
the readability and clarity of the code (quotation marks,
newline escapes, and concatenation operators)
DS – NLU 230
A text block begins with three double-quote characters
followed by a line terminator.
DS – NLU 231
A multi-line string without that final line
DS – NLU 232
([Link])
233
The record is a new type of class in Java that makes it easy to
create immutable data objects.
A new syntax that is specific for records.
DS – NLU 234
The compiler can infer the internal fields, and generate
constructor from fields.
The compiler provides sensible implementations for the
getters, toString, equals, and hashCode methods
Record cannot extend any class,
Record can implement interfaces
Record cannot be a superclass
DS – NLU 235
Sealed classes and interfaces restrict
which other classes or interfaces may
extend or implement them.
236
final: Cannot be extended further
DS – NLU 237
To seal a class, add the sealed modifier to its declaration.
Then, after any extends and implements clauses, add the
permits clause
Declare:
DS – NLU 238
To seal an interface, add the sealed modifier to its
declaration.
Usage:
DS – NLU 239
Usage (cont.):
DS – NLU 240
Usage (cont.):
-104
DS – NLU 241
FACULTY OF INFORMATION TECHNOLOGY
DS – NLU 244
DS – NLU 245
Product maxProduct() tìm ra sản phẩm bán ra nhiều nhất
DS – NLU 246
Class OrderManager
DS – NLU 247
Class Order
DS – NLU 248
Class OrderManager
TreeSet<Order> ordersByCost() sắp xếp các hóa đơn theo giá trị hóa
đơn, nếu trùng thì sắp xếp theo nhân viên lập hóa đơn.
DS – NLU 249
Cho class diagram dưới đây:
DS – NLU 250
Cho class diagram dưới đây:
DS – NLU 251
Phương thức public Course getMaxPracticalCourse() trả về course thực
hành có nhiều sinh viên đăng ký học nhất
DS – NLU 252
Cho class diagram dưới đây:
DS – NLU 253
Phương thức public Map<Integer, List<Student>>
groupStudentsByYear() để thống kê danh sách sinh viên theo năm vào
học, với key là năm vào học và value là các sinh viên tương ứng
DS – NLU 254
Cho class diagram dưới đây:
DS – NLU 255
Phương thức public Set<Course> filterCourses(String type) trả về các
course theo loại cho trước (type). Các course được sắp xếp giảm dần
theo số lượng sinh viên đăng ký học
DS – NLU 256