0% found this document useful (0 votes)
10 views46 pages

Java 8 Key Features Explained

Java 8 introduced significant features that transformed Java programming, including Lambda Expressions for functional programming, Functional Interfaces for defining single abstract methods, and various predefined functional interfaces like Predicate, Consumer, and Supplier. These enhancements allow for more concise and expressive code, enabling developers to utilize functional programming paradigms effectively. The document provides examples and explanations of these features, showcasing their practical applications in Java development.
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)
10 views46 pages

Java 8 Key Features Explained

Java 8 introduced significant features that transformed Java programming, including Lambda Expressions for functional programming, Functional Interfaces for defining single abstract methods, and various predefined functional interfaces like Predicate, Consumer, and Supplier. These enhancements allow for more concise and expressive code, enabling developers to utilize functional programming paradigms effectively. The document provides examples and explanations of these features, showcasing their practical applications in Java development.
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

Java 8 Features [Link]

com/java-8-features

Appearance Add new Edit this post

Java 8 Features
Java 8 introduced several new features and
enhancements that revolutionized the way developers
write Java code. Here's a breakdown of the key
features:

Java 8 introduced several new features and enhancements that


revolutionized the way developers write Java code. Here's a
breakdown of the key features:

Java 8 introduced several new features and enhancements that


revolutionized the way developers write Java code. Here's a
breakdown of the key features:

1. Lambda Expressions
• Description: Enables functional programming by
allowing you to write anonymous functions (short
and concise).
• Syntax:

(parameters) -> expression


List<String> names = [Link]("Nitesh", "Kr",
"Synergy");

1 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link](name -> [Link](name));


Appearance Add new Edit this post

package [Link].java8;

import [Link];
import [Link];
import [Link];
import [Link].*;

public class Java8Demo1 {


public static void main(String[] args) {

// Lambda for Addition


Calculator add = (a, b) -> a + b;

// Lambda for Subtraction


Calculator subtract = (a, b) -> a - b;

// Lambda for Multiplication


Calculator multiply = (a, b) -> a * b;

// Lambda for Division (Handles division by zero with


a fallback value of 0)
Calculator divide = (a, b) -> b != 0 ? a / b : 0;

// Demonstrate usage of Calculator lambdas


[Link]("Addition: " + [Link](10,
5)); // Output: 15
[Link]("Subtraction: " +
[Link](10, 5)); // Output: 5
[Link]("Multiplication: " +
[Link](10, 5)); // Output: 50
[Link]("Division: " + [Link](10,
5)); // Output: 2

// List of names for sorting demonstration


List<String> names = [Link]("Alice", "Bob",
"Charlie", "David");

// Lambda for custom sorting by string length


[Link]((a, b) -> [Link]([Link](),
[Link]()));

[Link]("Sorted Names: " + names); //

2 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Output: Sorted list by name length


Appearance Add new Edit this post
// Predicate to check if a number is positive
Predicate<Integer> predicate = i -> i > 0;
if ([Link](10)) // Test predicate with value
10
[Link]("Positive");
else
[Link]("Negative");

// Consumer to print a string with a welcome message


Consumer<String> consumer = s -> {
[Link](s + " welcome"); // Print
message with "welcome"
};
[Link]("Nitesh"); // Output: Nitesh welcome

// Consumer to check if a number is even


Consumer<Integer> integerConsumer = number -> {
if (number % 2 == 0)
[Link]("Even");
};
[Link](2); // Output: Even

// List of integers for predicate demonstration


List<Integer> integerList = [Link](1, 2, 3, 4,
5, 6, 7, 8, 9);

// Predicate to check if a number is positive


Predicate<Integer> isPositive = n -> n > 0;

[Link]([Link](5)); // Output:
true
[Link]([Link](-3)); // Output:
false

// List of names for consumer demonstration


List<String> names1 = [Link]("Alice", "Bob",
"Charlie");
Consumer<String> printName = name ->
[Link](name);

// Use forEach with Consumer to print each name


[Link](printName); // Output: Alice, Bob,
Charlie

// Supplier to generate a random number


Supplier<Integer> randomNumber = () -> new
Random().nextInt(100);

3 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link]([Link]()); // Output:
Appearance Add new Edit this post
Random number (e.g., 42)
[Link]([Link]()); // Output:
Another random number (e.g., 85)

// Function to convert a string to uppercase


Function<String, String> toUpperCase = str ->
[Link]();

[Link]([Link]("hello")); //
Output: HELLO
[Link]([Link]("java")); //
Output: JAVA

// BiFunction to concatenate two strings


BiFunction<String, String, String> concatenate =
(str1, str2) -> str1 + str2;

[Link]([Link]("Hello, ",
"World!")); // Output: Hello, World!
[Link]([Link]("Java ", "8"));
// Output: Java 8
}
}

// Functional Interface for basic calculator operations


@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}

• 1. Functional Interface ( Calculator ):


◦ Defines the calculate method for custom
arithmetic operations (addition,
subtraction, etc.).
2. Lambdas for Arithmetic Operations ( add ,
subtract , multiply , divide ):
◦ Implements operations like a + b (line:
Calculator add = ... ).
3. Predicate Example ( Predicate<Integer> ):
◦ test method checks if a number is positive
( Predicate<Integer> predicate = ... ).
4. Consumer for String ( Consumer<String> ):
◦ accept method appends "welcome" and prints
a message ( Consumer<String> consumer =

4 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

... ).
Appearance Add new Edit this post
5. Consumer for Integer ( Consumer<Integer> ):
◦ Checks if a number is even
( Consumer<Integer> integerConsumer = ... ).
6. Sorting Names ( [Link] ):
◦ Sorts a list by string length using a
lambda ( [Link]((a, b) -> ...) ).
7. forEach Method ( [Link](printName) ):
◦ Iterates over a list of names and prints
each ( Consumer<String> printName = ... ).
8. Supplier for Random Numbers
( Supplier<Integer> ):
◦ Generates random numbers ( Supplier<Integer>
randomNumber = ... ).
9. Function for String Transformation
( Function<String, String> ):
◦ Converts strings to uppercase
( Function<String, String> toUpperCase =
... ).
10. BiFunction for Concatenation
( BiFunction<String, String, String> ):
◦ Combines two strings into one
( BiFunction<String, String, String>
concatenate = ... ).

2. Functional Interfaces
• Description: An interface with a single abstract
method (SAM).
• Key Annotation: @FunctionalInterface (Optional
but recommended).
• Common Interfaces:
◦ Predicate<T> : Takes one argument, returns a
boolean.
◦ Consumer<T> : Takes one argument, returns
nothing.
◦ Function<T, R> : Takes one argument, returns a
result.

5 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

@FunctionalInterface
Appearance Add new Edit this post
interface Greeting {
void sayHello(String name);
}

Greeting greeting = name -> [Link]("Hello, " +


name);
[Link]("Nitesh");

List of Predefined Functional


Interfaces in Java 8
Java 8 provides several predefined functional interfaces in
the [Link] package:

1. Consumer
• Purpose: Represents an operation that takes a
single input and performs an action without
returning a result.
• Methods:
◦ void accept(T t)

2. Supplier
• Purpose: Represents a function that supplies a
value without taking any input.
• Methods:
◦ T get()

3. Predicate
• Purpose: Represents a condition (boolean-valued
function) on a single input.
• Methods:
◦ boolean test(T t)

4. Function
• Purpose: Represents a function that takes one
input and produces one output.
• Methods:

6 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

◦ R Add
Appearance
apply(T
new
t)
Edit this post

5. BiFunction
• Purpose: Represents a function that takes two
inputs and produces one output.
• Methods:
◦ R apply(T t, U u)

6. UnaryOperator
• Purpose: A specialization of Function for
operations on a single operand that return the
same type.
• Methods:
◦ T apply(T t)

7. BinaryOperator
• Purpose: A specialization of BiFunction for
operations on two operands of the same type that
return the same type.
• Methods:
◦ T apply(T t1, T t2)

8. BiConsumer
• Purpose: Represents an operation that takes two
inputs and performs an action without returning a
result.
• Methods:
◦ void accept(T t, U u)

9. DoublePredicate,
IntPredicate, LongPredicate
• Purpose: Specialized versions of Predicate for
double , int , and long types.
• Methods:
◦ boolean test(double d) (or int / long )

7 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

10. DAdd
ounew
Appearance bleEdit
Cothisnpost
sumer,
IntConsumer, LongConsumer
• Purpose: Specialized versions of Consumer for
double , int , and long types.
• Methods:
◦ void accept(double d) (or int / long )

11. ToDoubleFunction,
ToIntFunction, ToLongFunction
• Purpose: Converts an input to a double , int , or
long respectively.
• Methods:
◦ double applyAsDouble(T t) (or int / long )

12. ToDoubleBiFunction,
ToIntBiFunction,
ToLongBiFunction
• Purpose: Converts two inputs to a double , int , or
long respectively.
• Methods:
◦ double applyAsDouble(T t, U u) (or int / long )

13. DoubleSupplier,
IntSupplier, LongSupplier
• Purpose: Specialized versions of Supplier for
double , int , and long types.
• Methods:
◦ double getAsDouble() (or int / long )

14. ObjDoubleConsumer,
ObjIntConsumer,
ObjLongConsumer

8 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

• PurposAdd
Appearance
e: new
Takes Edit
an this
object
post
and a primitive type
( double , int , or long ) and performs an
operation.
• Methods:
◦ void accept(T t, double d) (or int / long )

15. Comparator (from


[Link] )
• Purpose: Compares two objects for ordering.
• Methods:
◦ int compare(T o1, T o2)

These interfaces are building blocks for functional


programming in Java and are commonly used with lambda
expressions and method references.

Predefined Functional Interfaces in


Java (Before Java 8 and Other
Libraries)

1. Runnable (Introduced in
Java 1.0)
• Purpose: Represents a task that can be run
concurrently in a thread.
• Method:
◦ void run()

2. Callable (Introduced in
Java 5)
• Purpose: Represents a task that can return a
result and may throw an exception.
• Method:
◦ V call() throws Exception

3. Comparator (Introduced in

9 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Java Add
1.2,
Appearance new present
Edit this post in
[Link] package)
• Purpose: Compares two objects for ordering.
• Method:
◦ int compare(T o1, T o2)

4. ActionListener (Introduced
in Java 1.0)
• Purpose: Represents an action event listener for
GUI components.
• Method:
◦ void actionPerformed(ActionEvent e)

5. EventListener (Introduced
in Java 1.0)
• Purpose: Represents the general interface for all
event listeners.
• Method: No method (marker interface for event
handling)

6. RunnableFuture (Introduced
in Java 5)
• Purpose: Extends Runnable and Future , combining
the ability to run a task and return a result.
• Method:
◦ boolean cancel(boolean mayInterruptIfRunning)
◦ V get()

7. Predicate (Before Java 8)


• While Predicate<T> was formally introduced in
Java 8, a simple condition-checking pattern (like
boolean test(T t) ) can be implemented in earlier
versions manually.

10 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

8. StAdd
renew
Appearance am’Edit
s thisforEach
post (Prior
to Java 8)
• Even before Java 8's [Link]() , you could
use loops or iterators for similar purposes,
though Stream itself was introduced in Java 8.

Other Common Java Functional


Interfaces

1. Optional (Java 8)
• While Optional itself isn't a functional
interface, it often works with functional
programming principles. It is used to represent a
value that may or may not be present.

2. Observer (Java 1.0)


• Purpose: Allows an object to listen to and react
to state changes in another object (older event-
based model).
• Method:
◦ void update(Observable o, Object arg)

3. Iterable (Java 1.0)


• Purpose: Represents a collection of elements that
can be iterated.
• Method:
◦ Iterator<T> iterator()

Java 8 introduced the most significant collection of


predefined functional interfaces ( Function , Predicate ,
Consumer , Supplier , etc.). Before Java 8, there were
functional-like interfaces such as Runnable , Callable , and
Comparator , but Java 8 provided a formal structure for
lambda expressions and functional programming. Additionally,

11 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

libraries like Guava, Apache Commons, and Spring further


Appearance Add new Edit this post
expanded the list of functional interfaces for specialized
use cases.

Key Functional Interfaces in


[Link]
1. Consumer<T>
• Definition: Represents an operation that
accepts a single input argument and returns no
result.
• Use Case: Used for performing side-effect
operations like printing, modifying a variable,
etc.
• Method:
◦ void accept(T t)
• Code Example:

import [Link];

public class ConsumerExample {


public static void main(String[] args) {
Consumer<String> printConsumer = str ->
[Link](str);
[Link]("Hello, Consumer!");
}
}
Output: Hello, Consumer!

Supplier<T>

• Definition: Represents a supplier of results. It


does not take any input but returns a result.
• Use Case: Used for generating or supplying
objects, often in lazy evaluation.
• Method:
◦ T get()
• Code Example:

12 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

import [Link];
Appearance Add new Edit this post
public class SupplierExample {
public static void main(String[] args) {
Supplier<Integer> randomNumber = () -> (int)
([Link]() * 100);
[Link]("Random number: " +
[Link]());
}
}


◦ Output: Random number like 42

Predicate<T>

• Definition: Represents a predicate (boolean-valued


function) of one argument.
• Use Case: Used for testing conditions and
filtering.
• Method:
◦ boolean test(T t)
• Code Example:

import [Link];

public class PredicateExample {


public static void main(String[] args) {
Predicate<Integer> isEven = num -> num % 2 == 0;
[Link]([Link](4)); // Output: true
[Link]([Link](5)); // Output: false
}
}

Output:

true false

13 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance Add new Edit this post

Function<T, R>

• Definition: Represents a function that accepts one


argument and produces a result.
• Use Case: Used for transforming or computing
results based on an input.
• Method:
◦ R apply(T t)
• Code Example:

import [Link];

public class FunctionExample {


public static void main(String[] args) {
Function<String, Integer> stringLength = str ->
[Link]();
[Link]("Length of 'Hello': " +
[Link]("Hello"));
}
}


▪ Output: Length of 'Hello': 5

BiConsumer<T, U>

◦ Definition: Represents an operation that


accepts two input arguments and returns no
result.
◦ Use Case: Used for performing operations on
pairs of values, like logging or modifying two
variables.
◦ Method:
▪ void accept(T t, U u)

import [Link];

public class BiConsumerExample {


public static void main(String[] args) {

14 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

BiConsumer<String, Integer> printNameAndAge =


Appearance Add new Edit this post
(name, age) ->
[Link](name + " is " + age + "
years old.");
[Link]("Alice", 25);
}
}


▪ Output: Alice is 25 years old.

BiFunction<T, U, R>

◦ Definition: Represents a function that accepts


two arguments and produces a result.
◦ Use Case: Used for performing transformations
or computations on pairs of values.
◦ Method:
▪ R apply(T t, U u)
◦ Code Example:

import [Link];

public class BiFunctionExample {


public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> add =
(a, b) -> a + b;
[Link]("Sum: " + [Link](5, 3));
}
}


▪ Output: Sum: 8

UnaryOperator<T>

15 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance
Denew
▪Add finitiEdit
on:this
A post
special case of Function that
takes one argument of type T and returns a
result of the same type T .
▪ Use Case: Used for operations that return
the same type of input.
▪ Method:
▪ T apply(T t)
▪ Code Example:

import [Link];

public class UnaryOperatorExample {


public static void main(String[] args) {
UnaryOperator<String> toUpperCase = str ->
[Link]();

[Link]([Link]("hello"));
}
}

▪ Output: HELLO

BinaryOperator<T>

▪ Definition: A special case of


BiFunction where both input arguments
and the return type are of the same type
T.
▪ Use Case: Used for combining two values
of the same type.
▪ Method:
▪ T apply(T t1, T t2)
▪ Code Example:

import [Link];

public class BinaryOperatorExample {


public static void main(String[] args) {
BinaryOperator<Integer> multiply = (a,
b) -> a * b;

16 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link]("Multiplication: " +
Appearance Add new Edit this post
[Link](4, 5));
}
}

▪ Output: Multiplication: 20

1. ToIntFunction<T>
▪ Definition: Represents a function
that takes one argument and
returns an int value.
▪ Use Case: Used for extracting an
int value from an object.
▪ Method:
▪ int applyAsInt(T t)
▪ Code Example:

import
[Link]
tion; public class
ToIntFunctionExample {
public static void main
(String[] args) {
ToIntFunction<String>
stringToLength = str ->
[Link]();
[Link]("Length:
" +
[Link]("J
ava" )); } }

Output: Length: 4

2. ToDoubleFunction<T>
▪ Definition: Represents a function
that takes one argument and
returns a double value.
▪ Use Case: Used for extracting a

17 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

double value from an object.


Appearance Add new Edit this post
▪ Method:
▪ double applyAsDouble(T t)
▪ Code Example:

import
[Link]
unction; public class
ToDoubleFunctionExample {
public static void main
(String[] args) {
ToDoubleFunction<String>
stringToDouble = str ->
[Link]() * 1.5 ;
[Link]("Double
value: " +
[Link]
("Java" )); } }

Output: Double value: 6.0

Summary of Use Cases:


▪ Consumer: Performing actions (e.g.,
printing or modifying data).
▪ Supplier: Providing data or
generating results (e.g., random
numbers, factory methods).
▪ Predicate: Testing conditions (e.g.,
checking for even numbers, filtering
elements).
▪ Function: Transforming or computing
results based on input (e.g., string
length, converting data types).
▪ BiConsumer: Handling two input
arguments (e.g., processing pairs of
values).
▪ BiFunction: Performing operations on
pairs of arguments (e.g., adding two
integers).

18 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance Add new


▪ UnaryOperator: Modifying a single
Edit this post
argument and returning the same type
(e.g., uppercasing a string).
▪ BinaryOperator: Combining two values
of the same type (e.g., adding two
integers).
▪ ToIntFunction/ToDoubleFunction:
Extracting primitive types from
objects (e.g., length of string as
integer or double).

package [Link].java8;

import [Link].*;

public class Demo02FunctionTypes {


public static void main(String[] args) {

// Consumer Example: Performing an


action without returning anything
Consumer<String> printConsumer = str ->
[Link]("Consumer Output: " + str);
[Link]("Hello,
Consumer!");

// Supplier Example: Providing a value


Supplier<Integer> randomNumber = () ->
(int)([Link]() * 100);
[Link]("Supplier Output: "
+ [Link]());

// Predicate Example: Testing a


condition
Predicate<Integer> isEven = num -> num
% 2 == 0;
[Link]("Predicate Output:
Is 4 even? " + [Link](4));
[Link]("Predicate Output:
Is 5 even? " + [Link](5));

19 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

// Function Example: Transforming an


Appearance Add new Edit this post
input to an output
Function<String, Integer> stringLength
= str -> [Link]();
[Link]("Function Output:
Length of 'Java' is " +
[Link]("Java"));

// BiConsumer Example: Performing an


action on two input values
BiConsumer<String, Integer>
printNameAndAge = (name, age) ->
[Link]("BiConsumer
Output: " + name + " is " + age + " years
old.");
[Link]("Alice", 30);

// BiFunction Example: Performing a


transformation on two input values
BiFunction<Integer, Integer, Integer>
addNumbers = (a, b) -> a + b;
[Link]("BiFunction Output:
Sum of 5 and 3 is " + [Link](5, 3));

// UnaryOperator Example: Applying an


operation on a single argument
UnaryOperator<String> toUpperCase = str
-> [Link]();
[Link]("UnaryOperator
Output: 'hello' to uppercase is " +
[Link]("hello"));

// BinaryOperator Example: Applying an


operation on two arguments of the same type
BinaryOperator<Integer> multiplyNumbers
= (a, b) -> a * b;
[Link]("BinaryOperator
Output: Product of 4 and 5 is " +
[Link](4, 5));

// ToIntFunction Example: Extracting an


integer value from an input
ToIntFunction<String> stringToLength =
str -> [Link]();
[Link]("ToIntFunction
Output: Length of 'Hello' is " +
[Link]("Hello"));

20 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance Add new Edit this post


// ToDoubleFunction Example: Extracting
a double value from an input
ToDoubleFunction<String> stringToDouble
= str -> [Link]() * 1.5;
[Link]("ToDoubleFunction
Output: Length of 'Hello' as double is " +
[Link]("Hello"));
}
}

Output Example:
Consumer Output: Hello, Consumer!
Supplier Output: 42
Predicate Output: Is 4 even? true
Predicate Output: Is 5 even? false
Function Output: Length of 'Java' is 4
BiConsumer Output: Alice is 30 years old.
BiFunction Output: Sum of 5 and 3 is 8
UnaryOperator Output: 'hello' to uppercase is
HELLO
BinaryOperator Output: Product of 4 and 5 is
20
ToIntFunction Output: Length of 'Hello' is 5
ToDoubleFunction Output: Length of 'Hello' as
double is 7.5

Explanation of Code:
1. Consumer: Prints a string to the
console.
2. Supplier: Generates and returns a
random number between 0 and 100.
3. Predicate: Checks if a number is even
(returns true or false ).
4. Function: Takes a string and returns
its length.

21 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

5. BiConsumer: Prints a person's name


Appearance Add new Edit this post
and age.
6. BiFunction: Adds two numbers and
returns their sum.
7. UnaryOperator: Converts a string to
uppercase.
8. BinaryOperator: Multiplies two
integers and returns the result.
9. ToIntFunction: Returns the length of
a string as an integer.
10. ToDoubleFunction: Multiplies the
length of a string by 1.5 and returns
the result as a double.

package [Link].java8;

import [Link];
import [Link];
import [Link];
import [Link].*;

public class FunctionTypes {


public static void main(String[] args) {
// List of names for example usage
List<String> names =
[Link]("Alice", "Bob", "Charlie",
"David");

// Predicate example: checking if a


number is positive
Predicate<Integer> predicate = i -> i >
0; // Predicate checks a condition on a
single input
if ([Link](10))
[Link]("Positive"); //
Will print "Positive" as 10 is greater than 0
else
[Link]("Negative"); //
Will not print

// Consumer example: accepting a string


and printing a message
Consumer<String> consumer = s -> {
[Link](s + " welcome");

22 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

// This prints a welcome message


Appearance Add new Edit this post
};
[Link]("Nitesh"); // Will
print "Nitesh welcome"

// Another Consumer example: checking


if an integer is even and printing
Consumer<Integer> integerConsumer = num
-> {
if (num % 2 == 0)
[Link]("Even"); //
Prints "Even" if the number is even
};
[Link](2); // Will
print "Even"

// List of integers for predicate


testing
List<Integer> integerList =
[Link](1, 2, 3, 4, 5, 6, 7, 8, 9);

// Predicate example: checking if a


number is positive
Predicate<Integer> isPositive = n -> n
> 0;
[Link]([Link](5));
// Output: true (5 is positive)

[Link]([Link](-3)); //
Output: false (-3 is negative)

// Consumer example: printing each name


from the list
List<String> names1 =
[Link]("Alice", "Bob", "Charlie");
Consumer<String> printName = name ->
[Link](name);
[Link](printName); // Output:
Alice, Bob, Charlie

// Supplier example: generating a


random number
Supplier<Integer> randomNumber = () ->
new Random().nextInt(100); // Generates a
random number between 0 and 99
[Link]([Link]());
// Output: Random number (e.g., 42)
[Link]([Link]());

23 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

// Output: Another random number (e.g., 85)


Appearance Add new Edit this post
// Function example: converting a
string to uppercase
Function<String, String> toUpperCase =
str -> [Link](); // Converts string
to uppercase

[Link]([Link]("hello"));
// Output: HELLO

[Link]([Link]("java"));
// Output: JAVA

// BiFunction example: concatenating


two strings
BiFunction<String, String, String>
concatenate = (str1, str2) -> str1 + str2;

[Link]([Link]("Hello,
", "World!")); // Output: Hello, World!

[Link]([Link]("Java ",
"8")); // Output: Java 8
}
}

→ Next

In Java 8, Streams provide a powerful way to


process sequences of elements (such as
collections or arrays) in a functional style.
They allow you to process data in a concise
and declarative manner, which improves code
readability and maintainability. Streams can
be created from collections, arrays, or
individual values.

1. Creating Streams from


Collections

24 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

A Collection (e.g., List , Set ) is one of the


Appearance Add new Edit this post
most common sources of data from which you can
create a stream.

▪ Using stream() method: Collections


in Java 8 implement the Stream
interface, and you can create a
stream using the stream() method.
import [Link];
import [Link];

public class StreamFromCollection {


public static void main(String[] args) {
List<String> names =
[Link]("Alice", "Bob", "Charlie",
"David");

// Create a stream from a collection


[Link]()
.filter(name ->
[Link]("A"))
.forEach([Link]::println); //
Output: Alice
}
}

Explanation: Here, we use the stream() method


to create a stream from the List . We then use
operations like filter() to process the
elements in the stream. The forEach()
terminal operation prints the result.

Creating Streams from Arrays


Arrays are another common data source for
streams in Java. You can create a stream from
an array using the [Link]() method or
the stream() method (if working with arrays
in general).

▪ Using [Link]() :
import [Link];

25 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

public class StreamFromArray {


Appearance Add new Edit this post
public static void main(String[] args) {
String[] fruits = {"Apple", "Banana",
"Mango", "Pineapple"};

// Create a stream from an array


[Link](fruits)
.filter(fruit -> [Link]() >
5)
.forEach([Link]::println);
// Output: Banana, Mango, Pineapple
}
}
Explanation: The [Link]() method
creates a stream from the array fruits . The
stream operations such as filter() and
forEach() are used to process the elements.

Creating Streams from


Individual Values
In addition to collections and arrays, you can
create streams from individual values using
the [Link]() method. This method is useful
when you want to create a stream from a small
number of elements.

▪ Using [Link]() :

import [Link];

public class StreamFromValues {


public static void main(String[] args) {
// Create a stream from individual
values
Stream<String> stream =
[Link]("John", "Jane", "Mike", "Anna");

// Use operations on the stream


[Link](name -> [Link]() >
3)
.forEach([Link]::println);

26 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

// Output: John, Jane, Mike


Appearance Add new Edit this post
}
}

Explanation: Here, we use [Link]() to


create a stream from individual values. We
apply the filter() operation to select names
with more than 3 characters, and forEach() is
used to print the filtered results.

Creating Streams from


Primitive Arrays
For arrays of primitive types (e.g., int[] ,
double[] , etc.), Java provides specialized
stream types: IntStream , LongStream , and
DoubleStream . These allow efficient handling
of primitive data types without the overhead
of autoboxing.

▪ Using [Link]() for primitive


arrays:

Example:

import [Link];

public class StreamFromPrimitiveArray {


public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};

// Create an IntStream from an int


array
[Link](numbers)
.filter(num -> num % 2 == 0)
.forEach([Link]::println);
// Output: 2, 4
}
}
Explanation: We create an IntStream from the
int[] array using [Link]() . The
filter() method is applied to select even
numbers, and forEach() prints the results.

27 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance Add new Edit this post

Summary of Ways to Create


Streams:

Method to
Source Example
Create Stream

List<String> list =
Collection stream() method
...; [Link]()

[Link]() int[] arr = ...;


Array
method [Link](arr)

Stream<String> stream
Individual [Link]()
= [Link]("a", "b",
Values method
"c")

[Link]()
int[] numbers = {1,
Primitive for primitive
2, 3};
Arrays types ( int[] ,
[Link](numbers)
double[] )

Why Use Streams?


1. Declarative and Functional Style:
Streams allow you to process data in
a more functional way, making the
code more readable and concise.
Instead of writing explicit loops and
conditional statements, you can use
operations like filter() , map() ,
reduce() , and more.
2. Parallel Processing: Streams can
easily be processed in parallel,
improving performance on multi-core
systems.
3. Chainable Operations: Streams support
method chaining, enabling you to
apply multiple operations in a
fluent, readable manner.

28 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

Appearance Real-World
Add new Edit this post Use Case
(Gaming):
In a gaming project, suppose you have a list
of players, and you want to filter out all
players whose scores are below a certain
threshold and then sort the remaining players
by their scores.

import [Link];
import [Link];
import [Link];

class Player {
String name;
int score;

Player(String name, int score) {


[Link] = name;
[Link] = score;
}

public String toString() {


return name + ": " + score;
}
}

public class StreamExample {


public static void main(String[] args) {
List<Player> players = [Link](
new Player("Alice", 1500),
new Player("Bob", 800),
new Player("Charlie", 1200),
new Player("David", 2000)
);

// Use streams to filter and sort


List<Player> filteredPlayers =
[Link]()
.filter(player -> [Link]
> 1000)
.sorted((p1, p2) ->
[Link]([Link], [Link])) // Sort
by score descending

29 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

.collect([Link]());
Appearance Add new Edit this post

[Link]([Link]::println);
// Output: David: 2000, Alice: 1500, Charlie:
1200
}
}

In Java 8, the Stream API provides a set of


operations to process sequences of elements in
a functional style. The Stream API can be
categorized into two main types based on how
data flows and is processed: Streams and
Primitive Streams.

Here’s a breakdown of the types of Stream API


in Java:

1. Stream (Reference Type


Stream)
▪ Stream<T>: The general stream type for
working with objects (non-primitive
types).

▪ Purpose: Used to process data


that is wrapped in reference
types (e.g., String , Integer ,
Custom objects ).
▪ Operations: Can perform
operations like filtering,
mapping, sorting, reducing, etc.,
on objects.
Example:

import [Link];
import [Link];

public class ReferenceStreamExample {


public static void main(String[] args) {
List<String> names =

30 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link]("Alice", "Bob", "Charlie",


Appearance Add new Edit this post
"David");

[Link]()
.filter(name -> [Link]() > 3)
.forEach([Link]::println); //
Output: Alice, Charlie, David
}
}

Features:

▪ Supports operations like map() ,


filter() , forEach() , reduce() .
▪ Allows creating a pipeline of
multiple operations on collections or
other data sources.
▪ Does not support primitive operations
directly.

Primitive Streams
▪ IntStream, LongStream, and DoubleStream:
These are specialized streams for handling
primitive types ( int , long , and double ),
providing better performance by avoiding
autoboxing (the conversion between
primitives and objects).

▪ IntStream: Used for int values.


▪ LongStream: Used for long values.
▪ DoubleStream: Used for double
values.
Why Primitive Streams?

▪ Efficiency: They avoid the


overhead of boxing and unboxing
primitive values into wrapper
classes like Integer , Long , and
Double .
▪ Specialized Operations: These

31 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

streams support operations like


Appearance Add new Edit this post
sum() , average() , and min() ,
which are optimized for primitive
data types.
Example:

import [Link];

public class PrimitiveStreamExample {


public static void main(String[] args) {
[Link](1, 6)
.filter(n -> n % 2 == 0)
.forEach([Link]::println);
// Output: 2, 4
}
}

Features:

▪ IntStream: Provides methods like


sum() , average() , max() , and min() .
▪ LongStream and DoubleStream: Similar
methods as IntStream but for long
and double data types, respectively.
▪ They offer mapToObj() ,
flatMapToInt() , etc., to transform
between primitive and object streams.

Stream Pipelines and


Operations
Regardless of whether you're using reference
streams or primitive streams, the stream
operations can be categorized into:

▪ Intermediate Operations: These


operations transform a stream into
another stream (e.g., map() ,
filter() , distinct() ). They are

32 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

lazy, meaning they are not executed


Appearance Add new Edit this post
until a terminal operation is
invoked.
▪ Terminal Operations: These operations
produce a result or a side effect
(e.g., collect() , forEach() ,
reduce() ). A terminal operation
marks the end of the stream pipeline.
▪ Short-circuiting Operations: These
operations allow the processing to
stop early based on a condition, such
as anyMatch() , allMatch() ,
findFirst() , etc.

Key Differences Between


Stream Types:

For For Objects/


Stream Type Primitive Reference
Types Types

Stream No Yes

IntStream Yes No

LongStream Yes No

DoubleStream Yes No

Types Of Stream
API In Java 8

Intermediate operations are operations that

33 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

transform a stream into another stream. These


Appearance Add new Edit this post
operations are lazy, meaning they do not
perform any processing until a terminal
operation is invoked. When you perform
intermediate operations, you create a stream
pipeline that is executed when a terminal
operation is triggered. Since they are lazy,
intermediate operations can be chained
together and only evaluated when necessary,
which can help improve performance by avoiding
unnecessary computations.

Here are the key Intermediate Operations


available in Java 8 Streams:

package [Link];

import [Link];
import [Link].*;
import [Link];
import [Link];

public class Demo01IntermediateOperations {


public static void main(String[] args) {
// filter() – Filters elements based on
a condition
List<String> list1 =
[Link]("apple", "banana", "carrot",
"Mango", "Anans", "Appu", "Awla");
[Link]()
.filter(s ->
[Link]().startsWith("a"))
.forEach([Link]::println);

// map() – Transforms each element of


the stream
[Link]()
.map(s -> [Link]("a", "b"))
.forEach([Link]::println);

// distinct() – Removes duplicates


List<Integer> list2 = [Link](1,
2, 3, 4, 5, 6, 7, 8, 9);
[Link]()
.distinct()
.forEach([Link]::println);

// sorted() – Sorts the stream

34 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

List<Integer> list3 = [Link](9,


Appearance Add new Edit this post
1, 5, 3, 7, 2, 6, 8, 4);
[Link]()
.sorted()
.forEach([Link]::println);

// limit() – Limits the number of


elements in the stream
List<Integer> list4 = [Link](1,
2, 3, 4, 5, 6, 7, 8, 9);
[Link]()
.limit(5)
.forEach([Link]::println);

// skip() – Skips the first n elements


[Link]()
.skip(5)
.forEach([Link]::println);
}
}

Terminal Operations are the operations that


trigger the processing of the stream and
produce a result, a side-effect, or a final
computation. Once a terminal operation is
invoked, the stream is consumed and can no
longer be used. These operations mark the end
of the stream pipeline and cause the
intermediate operations to be evaluated.

Here’s a breakdown of some key Terminal


Operations in Java 8 Streams:

package [Link];

import [Link];
import [Link].*;
import [Link];
import [Link];

public class Demo03TerminalOperations {

public static void main(String[] args) {

// collect() – Collects elements into a

35 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

List
Appearance Add new Edit this post
List<String> list =
[Link]("apple", "banana", "cherry");

List<String> result = [Link]()

.collect([Link]());

[Link](result); // Output:
[apple, banana, cherry]

// collect() – Collects elements into a


Map using identity as key and entire list as
value
[Link]()

.collect([Link]([Link](),
l -> list))
.forEach((key, value) ->
[Link]("Identity: " + key + " => "
+ value));

// forEach() – Performs an action for


each element
[Link]()
.forEach([Link]::println);

// reduce() – Reduces the stream to a


single value (e.g., sum)
List<Integer> integers =
[Link](1,2,3,4,5,6,7,8,9,10);
Integer sum = [Link]()
.reduce(0,
Integer::sum);

[Link]("Sum using reduce():


" + sum);
}
}

Short-circuiting operations in Java 8 Streams


are special types of terminal operations that
terminate the stream processing early. These

36 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

operations evaluate the stream lazily, which


Appearance Add new Edit this post
means that they stop processing elements as
soon as the condition is met. This can result
in performance optimization, especially when
working with large datasets, as it avoids
unnecessary processing.

Short-circuiting operations are used when you


don’t need to process the entire stream, but
only a part of it. They "short-circuit" the
evaluation once a result is determined.

package [Link];

import [Link];
import [Link];
import [Link];

public class Demo04ShortCircuitingOperations {

public static void main(String[] args) {


List<Integer> list = [Link](1,
2, 3, 4, 5);

// anyMatch() – Returns true if any


element matches the condition
boolean anyMatch =
[Link]().anyMatch(x -> x > 4);
[Link]("Any match > 4: " +
anyMatch); // Output: true

// allMatch() – Returns true if all


elements match the condition
boolean allMatch =
[Link]().allMatch(x -> x > 0);
[Link]("All match > 0: " +
allMatch); // Output: true

// noneMatch() – Returns true if no


elements match the condition
boolean noneMatch =
[Link]().noneMatch(x -> x < 0);
[Link]("None match < 0: " +
noneMatch); // Output: true

// findFirst() – Returns the first


element in the stream
Optional<Integer> first =
[Link]().findFirst();

37 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link](val ->
Appearance Add new Edit this post
[Link]("First element: " + val));
// Output: 1

// findAny() – Returns any element from


the stream (useful in parallel streams)
Optional<Integer> any =
[Link]().findAny();
[Link](val ->
[Link]("Any element: " + val));
// Output: 1 (or any)
}
}

Gaming Example: Player


Ranking and Filtering
import [Link].*;
import [Link].*;

public class GamingExample {


public static void main(String[] args) {
// Creating a list of players with
scores and rankings
List<Player> players = [Link](
new Player("Alice", 1000, "Bronze",
[Link]("Quest1", "Quest2")),
new Player("Bob", 1500, "Gold",
[Link]("Quest2", "Quest3")),
new Player("Charlie", 2500,
"Platinum", [Link]("Quest1",
"Quest4")),
new Player("David", 800, "Silver",
[Link]("Quest3", "Quest5")),
new Player("Eve", 1300, "Gold",
[Link]("Quest4", "Quest6"))
);

// Stream pipeline to process players:


List<String> highRankingPlayers =
[Link]()
// 1. Filter out players who have
less than 1000 points
.filter(player -> [Link]()

38 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

>= 1000)
Appearance Add new Edit this post

// 2. Map the filtered players to


their names
.map(Player::getName)

// 3. Apply a transformation to
convert all player names to uppercase
.map(String::toUpperCase)

// 4. Filter players whose names


start with 'A'
.filter(name ->
[Link]("A"))

// 5. Convert the list of names to


a stream of quests each player is associated
with
.flatMap(name -> [Link]()

.filter(player ->
[Link]().equals(name))

.flatMap(player ->
[Link]().stream()))

// 6. Remove duplicate quests


.distinct()

// 7. Sort quests alphabetically


.sorted()

// 8. Limit the output to the first


3 quests
.limit(3)

// 9. Collect the result into a


List
.collect([Link]());

// Displaying the results


[Link]("High-ranking
players' quests: " + highRankingPlayers);
}
}

// Player class with name, score, rank, and

39 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

quests
Appearance Add new Edit this post
class Player {
private String name;
private int score;
private String rank;
private List<String> quests;

public Player(String name, int score,


String rank, List<String> quests) {
[Link] = name;
[Link] = score;
[Link] = rank;
[Link] = quests;
}

public String getName() {


return name;
}

public int getScore() {


return score;
}

public String getRank() {


return rank;
}

public List<String> getQuests() {


return quests;
}
}

Explanation of the Stream


Pipeline:
1. filter(player -> [Link]()
>= 1000) : Filters out players with
scores less than 1000, ensuring we
only process high-scoring players.
2. map(Player::getName) : Maps the
players to their names, extracting
the relevant data from each Player
object.
3. map(String::toUpperCase) : Converts
the player names to uppercase for

40 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

uniform formatting.
Appearance Add new Edit this post
4. filter(name ->
[Link]("A")) : Filters the
list of player names to only include
those starting with the letter "A".
5. flatMap(name ->
[Link]().filter(player ->
[Link]().equals(name)).flatM
ap(player ->
[Link]().stream())) : For
each player, we extract their quests,
and use flatMap to flatten the
nested lists into a single stream of
quest names.
6. distinct() : Removes any duplicate
quest names from the resulting
stream.
7. sorted() : Sorts the quest names in
alphabetical order.
8. limit(3) : Limits the result to the
first 3 quests, demonstrating a cap
on the stream's size.
9. collect([Link]()) :
Collects the result into a list,
which is the final output.
Output:
High-ranking players' quests: [Quest1, Quest2,
Quest3]

Java 8 Stream Operations


with 20 Method Chain
import [Link].*;
import [Link].*;

public class StreamMethodChainExample {


public static void main(String[] args) {
// Create a list of players with names,
scores, ranks, and quests

41 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

List<Player> players = [Link](


Appearance Add new Edit this post
new Player("Alice", 1000, "Bronze",
[Link]("Quest1", "Quest2")),
new Player("Bob", 1500, "Gold",
[Link]("Quest2", "Quest3")),
new Player("Charlie", 2500,
"Platinum", [Link]("Quest1",
"Quest4")),
new Player("David", 800, "Silver",
[Link]("Quest3", "Quest5")),
new Player("Eve", 1300, "Gold",
[Link]("Quest4", "Quest6"))
);

// Chain of 20 stream methods


List<String> result = [Link]()
// 1. Filter players with a score
greater than or equal to 1000
.filter(player -> [Link]()
>= 1000)
// 2. Map to player's name
.map(Player::getName)
// 3. Convert names to uppercase
.map(String::toUpperCase)
// 4. Filter names that start with
'A'
.filter(name ->
[Link]("A"))
// 5. Map to player's quests by
finding players by name
.flatMap(name -> [Link]()

.filter(player ->
[Link]().equals(name))

.flatMap(player ->
[Link]().stream()))
// 6. Remove duplicates from the
quest names
.distinct()
// 7. Sort quest names
alphabetically
.sorted()
// 8. Limit to the first 3 quest
names
.limit(3)

42 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

// 9. Map quests to their length


Appearance Add new Edit this post
.map(String::length)
// 10. Filter quests that are
longer than 4 characters
.filter(len -> len > 4)
// 11. Reduce to the total length
of quest names
.reduce(0, Integer::sum)
// 12. Add a constant value (total
length of all quests) to it
.map(totalLength -> totalLength +
10)
// 13. Convert the total length to
a string with a message
.map(length -> "Total quest name
length with 10 added: " + length)
// 14. Filter if the string length
is greater than 50
.filter(msg -> [Link]() > 50)
// 15. If not empty, concatenate "
- Completed" at the end
.map(msg -> msg + " - Completed")
// 16. Sort the final string list
alphabetically
.sorted()
// 17. Limit the results to top 1
string
.limit(1)
// 18. Convert to a list (collect)
.collect([Link]())
// 19. Print the result
.forEach([Link]::println);
}
}

// Player class with name, score, rank, and


quests
class Player {
private String name;
private int score;
private String rank;
private List<String> quests;

public Player(String name, int score,


String rank, List<String> quests) {
[Link] = name;
[Link] = score;

43 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

[Link] = rank;
Appearance Add new Edit this post
[Link] = quests;
}

public String getName() {


return name;
}

public int getScore() {


return score;
}

public String getRank() {


return rank;
}

public List<String> getQuests() {


return quests;
}
}

Explanation of the Stream Method Chain:

1. filter(player -> [Link]()


>= 1000) : Filters out players with a
score less than 1000.
2. map(Player::getName) : Extracts the
names of the filtered players.
3. map(String::toUpperCase) : Converts
all player names to uppercase.
4. filter(name ->
[Link]("A")) : Filters names
that start with "A".
5. flatMap() : Extracts quests of
players whose names match the
filtered ones.
6. distinct() : Removes any duplicate
quest names.
7. sorted() : Sorts the quest names
alphabetically.
8. limit(3) : Limits the result to the
first 3 quests.
9. map(String::length) : Converts each
quest name to its length.

44 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

10. filter(len -> len > 4) : Filters


Appearance Add new Edit this post
quest names with length greater than
4.
11. reduce(0, Integer::sum) : Reduces the
length of quest names to a total sum.
12. map(totalLength -> totalLength +
10) : Adds 10 to the total length.
13. map(length -> "Total quest name
length with 10 added: " + length) :
Converts the total length into a
string with a message.
14. filter(msg -> [Link]() > 50) :
Filters if the string message length
is greater than 50.
15. map(msg -> msg + " - Completed") :
Appends "- Completed" to the message.
16. sorted() : Sorts the final string
messages alphabetically.
17. limit(1) : Limits the final result to
only the top 1 string.
18. collect([Link]()) :
Collects the result into a list.
19. forEach([Link]::println) : Prints
the final result.
Output:
Total quest name length with
10 added: 17 - Completed

You can ask any query just


drop mail to us on
say@[Link]

Key Features of Optional in Java:


Avoiding Null Checks: Optional helps avoid explicit null

45 of 46 02/11/25, 10:21 am
Java 8 Features [Link]

checks. Instead of checking if (object == null), you can use


Appearance Add new Edit this post
Optional to wrap a potentially null value, making it easier
to handle the absence of a value without needing to
explicitly check for null.

 43 min read

 Nov 19, 2024

 By Nitesh Synergy

SHARE

46 of 46 02/11/25, 10:21 am

You might also like