0% found this document useful (0 votes)
5 views255 pages

DS8 JavaGenrics Java8 Features

The document discusses the introduction of generics in Java, highlighting the limitations of early Java versions that lacked this feature, which required manual casting and led to errors. It explains how generics improve type safety by allowing parameterized types, enabling compile-time type checking, and reducing runtime errors. Additionally, the document covers the use of wildcards, bounded wildcards, and the benefits of autoboxing, unboxing, varargs, and enums in Java programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views255 pages

DS8 JavaGenrics Java8 Features

The document discusses the introduction of generics in Java, highlighting the limitations of early Java versions that lacked this feature, which required manual casting and led to errors. It explains how generics improve type safety by allowing parameterized types, enabling compile-time type checking, and reducing runtime errors. Additionally, the document covers the use of wildcards, bounded wildcards, and the benefits of autoboxing, unboxing, varargs, and enums in Java programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

FACULTY OF INFORMATION TECHNOLOGY

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]());
}

 … and people often made mistakes!

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);
}

 In late 1990s, Sun Microsystems initiated a design process to


add generics to the language ...

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 = ...

 We should be able to do the same thing with object types


generated by classes!

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]());
}

 … and mistakes (usually) get caught!

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.

interface Collection<T> { ... }


interface List<T> extends Collection<T> { ...}
class LinkedList<T> implements List<T> { ...}
class ArrayList<T> implements List<T> { ... }

/* The following statements are all legal. */


List<String> l = new LinkedList<String>();
ArrayList<String> a = new ArrayList<String>();
Collection<String> c = a;
l = a;
c = l;

DS – NLU 11
 String is a subtype of Object so...
 ...is LinkedList<String> a subtype of LinkedList<Object>?

LinkedList<String> ls = new LinkedList<String>();


LinkedList<Object> lo = new LinkedList<Object>();

lo = ls; // Suppose this is legal


[Link](2110); //Type-checks: Integer subtype Object
String s = [Link](0); // Type-checks: ls is a List<String>

 But what would happen at run-time if we were able to actually


execute this code?
Compile
error
DS – NLU 12
 Java’s type system allows the analogous rule for arrays:

String[] as = new String[10];


Object[] ao = new Object[10];

ao = as; // Type-checks: considered outdated design


ao[0] = 2110; // Type-checks: Integer subtype Object
String s = as[0];//Type-checks: as is a String array

 What happens when this code is run? TRY IT OUT!


◦ It throws an ArrayStoreException! Because arrays are built into Java
right from the beginning, it could be defined to detect such errors

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:

/** Replace all values x in list ts by y. */


public void replaceAll(List<Double> ts, Double x, Double
y) {
for (int i = 0; i < [Link](); i = i + 1)
if ([Link]([Link](i), x))
[Link](i, y);
}

 We would like to rewrite the parameter declarations so this


method can be used for ANY list, no matter the type of its
elements.

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);
}

 Somehow, Java must be told that T is a type parameter and


not a real type.

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.

/** Replace all values x in list ts by y. */


public <T> void replaceAll(List<T> ts, T x, T y) {
for (int i = 0; i < [Link](); i = i + 1)
if ([Link]([Link](i), x))
[Link](i, y);
}

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);

 /*Illegal:Collection<Integer> is not a subtype of


Collection<Object>! */

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! */

 One can think of Collection<?> as a “Collection of some


unknown type of values”.

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...

void doIt(Collection<? super Integer> c) {


[Link](42); /* Legal! */
}
// ...
Collection<Object> c1 = ...
Now c can only be a Collection of
doIt(c1); /* Legal! */ some supertype of Integer, and 42 can
Collection<Float> c2 = ... be added to any such Collection
doIt(c2); /* Illegal! */

 “? super” is useful when you are only giving values to the


object, such as putting values into a Collection

DS – NLU 21
 “? extends” is useful for when you are only receiving values
from the object, such as getting values out of a Collection.

void doIt(Collection<? extends Shape> c) {


for (Shape s : c)
[Link]();
}
// ...
Collection<Circle> c = ...
doIt(c); /* Legal! */
Collection<Object> c = ...
doIt(c); /* Illegal! */

DS – NLU 22
 Wildcards can be nested. The following receives Collections from an
Iterable and then gives floats to those Collections.

void doIt(Iterable<? extends Collection<? super Float>>


cs) {
for (Collection<? super Float> c : cs)
[Link](0.0f);
}
// ...
List<Set<Float>> l = ...
doIt(l); /* Legal! */
Collection<List<Number>> c = ...
doIt(c); /* Legal! */
Iterable<Iterable<Float>> i = ...;
doIt(i); /* Illegal! */
ArrayList<?extends Set<?super Number>> a = ...
doIt(a); /* Legal! */

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)*/

 But wildcards are preferred when just as expressive.

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);
}

Integer, Double, Character, and String are all Comparable with


themselves

DS – NLU 26
 Type parameter: anything T that implements Comparable<T>

public static <T extends Comparable<T>>


int indexOf1(List<T> c, T x) {
}

DS – NLU 27
 Autoboxing is the automatic conversion that the Java compiler
makes between the primitive types and their corresponding object
wrapper classes.

 For example, converting an int to an Integer, a double to


a Double,..

DS – NLU 28
 Consider the following code:

 The compiler converts the previous code to the following at


runtime:

DS – NLU 29
 The Java compiler applies autoboxing when a primitive value
is:

◦ Passed as a parameter to a method that expects an object of the


corresponding wrapper class.

◦ Assigned to a variable of the corresponding wrapper class.

DS – NLU 30
 Converting an object of a wrapper type (Integer) to its
corresponding primitive (int) value.

 The Java compiler applies unboxing when an object of a


wrapper class is:
◦ Passed as a parameter to a method that expects a value of the
corresponding primitive type.
◦ Assigned to a variable of the corresponding primitive type.

DS – NLU 31
DS – NLU 32
 Autoboxing and unboxing lets developers write cleaner code,
making it easier to read.

 Support using primitive types and Wrapper class objects


interchangeably;

 Do not need to perform any typecasting explicitly.

DS – NLU 33
 A feature that simplifies the creation of methods that need to
take a variable number of arguments.

 This feature is called varargs and it is short-form for variable-


length arguments.

 (Prior to JDK 5), variable-length arguments could be handled


two ways:
◦ Using overloaded method(one for each);
◦ Putting the arguments into an array.

DS – NLU 34
 Syntax of varargs:

 We don't have to provide overloaded methods so less code.

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:

◦ Each method can only have one varargs parameter

◦ The varargs argument must be the last parameter

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.

 enum type can be passed as an argument to switch statement.

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.

 toString() method is overridden in [Link] class,which


returns enum constant name.

 enum can implement many interfaces.

DS – NLU 45
DS – NLU 46
 values() method can be used to return all values present
inside enum.

 Order is important in enums. By using ordinal() method, each


enum constant index can be found, just like array index.

 valueOf() method returns the enum constant of the specified


string value, if exists.

 These methods are present inside [Link].

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.

 enum and methods:


◦ enum can contain concrete methods only i.e. no any abstract method.

DS – NLU 49
DS – NLU 50
51
52
 Interfaces in Java 8 can now declare methods with
implementation code

◦ static methods inside interfaces

◦ default methods that allows you to provide a default implementation


for methods in an interface

DS – NLU 53
 Java 8 just added several methods to Collection interfaces

 If you defined a Collection subclass, did it just break?


 No! These were added as default methods
◦ Declared in an interface with the default keyword
◦ Given a body

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)

 It is a regular method that can declare variables, create objects, and


invoke other methods of the interface

 Every class implementing the interface gets the default method


automatically

 A class can override a default method to change or replace its behaviour

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.

 Second solution is to call the default method of the specified


interface using super.

DS – NLU 59
DS – NLU 60
DS – NLU 61
DS – NLU 62
 Semantics: (possible not override)

◦ A method defined in a class always overrides a default method. Default methods


in sub-interfaces override those in super-interfaces
◦ Remaining conflicts must be resolved by overriding
◦ New syntax for invoking a default method from the implementor
[Link].m(...): Important because m may be defined in two implemented interfaces, so can’t
use simply super.m(...)

 Benefits of default methods


◦ Extending an interface without breaking implementors
◦ Putting reusable code in an interface
 can reuse default methods from several interfaces
 known as traits in other languages (e.g. Scala)

DS – NLU 63
 Static Methods in Interface:

◦ defined in the interface with the keyword static

◦ contain the complete definition of the function

◦ cannot be overridden or changed in the implementation class.

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

◦ the same input always generates the same output

◦ no side-effects
 a function relies on, or modifies, something outside its parameters to do
something

◦ no explicit changing of state

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.

 Known as Single Abstract Method Interfaces (SAM Interfaces).

◦ It is a new feature in Java, which helps to achieve functional


programming approach.

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

◦ Formal logic introduced by Alonzo Church in the 1930's

◦ Everything is a function!

◦ Equivalent in power and expressiveness to Turing Machine

◦ Church-TuringThesis, ~1934

◦ A lambda (λ) is an anonymous function

 A function without a corresponding identifier (name)

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.

◦ A function that can be created without belonging to any class.

◦ A lambda expression can be passed around as if it was an object and


executed on demand.

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);

 Advantage (over lambdas)


◦ reuse existing method
 Needs type inference context for target type
◦ similar to lambda expressions

DS – NLU 111
 4 types of method references:
◦ Static method reference

◦ Instance Method (Bound receiver)

◦ Instance Method (UnBound receiver)

◦ 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

◦ non-static method w/ bound receiver: Expr::Method


 e.g. [Link]::println
([Link] is an instance of PrintStream)

DS – NLU 114
 Situation:

◦ instance method needs an instance on which it can be invoked

 called: receiver

 Two possibilities:

◦ receiver is explicitly provided in an expression

 called: bound receiver

◦ receiver is implicitly provided from the context

 called: unbound receiver

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)

 Example: List<String> stringList = ... ;


[Link]([Link]::print);

◦ With lambda receiver

[Link]((String s) -> [Link](s));

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)

Stream<String> stringStream = ... ;


[Link](String::compareToIgnoreCase);
◦ With lambda:

[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)

◦ (arg0, rest) -> [Link](rest) can be


ClassName::instanceMethod (arg0 is of type ClassName)
 This is unBound

◦ (args) -> [Link](args) can be


instance::instanceMethod
 This is Bound
DS – NLU 119
 Method references do not specify argument type(s)
 Compiler infers from context
◦ which overloaded version fits

List<String> stringList = ... ;


[Link]([Link]::print);
➔ void print(String s)

 Resort to lambda expressions


◦ if compiler fails or a different version should be used

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

List<Account> accountCol = ... ;


Stream<Account> accounts = [Link]();
Stream<Account> millionaires =
[Link](a -> [Link]() > 1000000);

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.

 Stream is functional in nature.


◦ Operations performed on a stream does not modify it's source.

 Stream is lazy and evaluates code only when required.


 The elements of a stream are only visited once during the life of a
stream.
◦ Like an Iterator, a new stream must be generated to revisit the same elements
of the source.
DS – NLU 126
DS – NLU 127
 Streams do not store their elements (remind)
◦ not a collection, but created from a collection, array, ...
◦ view/adaptor of a data source (collection, array, ...)

 Streams provide functional operations


forEach, filter, map, reduce, ...
◦ applied to elements of underlying data source

DS – NLU 128
 Actually applied functionality is two-folded
◦ user-defined: functionality passed as parameter
◦ framework method: stream operations

 Separation between “what to do” & “how to do”


◦ user => what functionality to apply
◦ library => how to apply functionality
(parallel/sequential, lazy/eager, out-of-order)

[Link](a -> [Link]() > 1000000);


[Link](a DS-> [Link]());
– NLU 129
 ... can be
◦ lambda expressions
◦ method references
◦ (inner classes)
 Example: forEach
void forEach(Consumer<? super T> consumer);
public interface Consumer<T> {
public void accept(T t);
}
[Link]((Account a) -> { [Link](); });
[Link](a -> [Link]());
[Link](Account::addInterest);
DS – NLU 130
 Efficient and shortcode
 A very easy way to do parallel computation without having to
worry about the multi-threading implementations.
 Providing a large set of operations that can be utilized in
many scenarios.
 Providing a more memory efficient way as the stream is closed
➔ no extra objects and variables created.
 A wide range of functionalities can be implemented (using
lambda expressions)

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

 Example: Convert each element of the list to uppercase

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.

“Flatten” a list of lists of strings


into a stream of strings

List of list-[[1, 2], [3, 4], [5, 6], [7, 8]]


List generate by flatMap-[1,
DS – NLU 2, 3, 4, 5, 6, 7, 8] 133
 Build a new sequence that is the result of a filter applied to
each element in the original collection
◦ A intermediate operation that consumes a stream and produces a
stream.

 Example: filter all elements that start with “A”

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

 No stream types for char and float


◦ use stream type of respective ‘bigger’ primitive type
◦ IntStream for char, and DoubleStream for float
 e.g. interface CharSequence contains:
 IntStream chars();

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>

 Partition a list of transactions into two groups: expensive and not


expensive
◦ returning a Map<Boolean, List<Transaction>>

 Create multilevel groupings such as grouping transactions by cities and


then further categorizing by whether they’re expensive or not
◦ returning a Map<String, Map<Boolean,
List<Transaction>>>
Collectors

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.

 The strategy for this operation is provided via the Collector


interface implementation.

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

 Used for collecting all Stream elements into a List instance

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.

double r = [Link]([Link] * theta);


 To facilitate the java programmer to access any static member
of a class directly. There is no need to qualify it by the class
name.

import static [Link];

import static [Link].*;


double r = cos(PI * theta);
DS – NLU 163
 [Link]():
◦ return an ArrayList or a LinkedList or any other implementation of the
List interface
 [Link]():
◦ return an HashSet or a LinkedHashSet or any other implementation of
the Set interface

 How to specific a concrete implementation of Set or List?

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

 A container object which may or may not contain a non-null


value.
◦ If a value is present, isPresent() will return true and get() will return the
value.

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.

 Defined in Iterable and Stream interface.

 In Java 8, we can loop a List with forEach + lambda expression


or method reference.

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.

 New methods has added to [Link] package that use


the JSR 166 Fork/Join parallelism common pool to provide
sorting of arrays in parallel.

 The methods are called parallelSort() and are overloaded for


all the primitive data types and Comparable objects.

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.

 An instance of current date:


LocalDate localDate = [Link]();

 A LocalDate for December 20, 2024


[Link](2024, 9, 20);
[Link]("2024-09-20");

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:

07:30, 6,true, 23:59:59.999999999

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

 There are about 40 different time zones, specified by ZoneId

 A Zone for Paris:


ZoneId zoneId = [Link]("Europe/Paris");

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

06:30, 06:30:30, 30, 30

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

 Run in the interactive manner

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:

 String methods may be applied to a text block:

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

 sealed: Can only be extended by its permitted subclasses

 non-sealed: Can be extended by unknown subclasses; a


sealed class cannot prevent its permitted subclasses from
doing this

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

 HashMap<String, Integer> productTypesStatistics()


trả về loại sản phẩm và số lượng bán ra cho mỗi loại

DS – NLU 247
Class Order

 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 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:

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 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:

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 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:

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 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

You might also like