Java 8
Java 8
ie
ch
Te
Lets understand how we implement java functions without java8
features.
g
rin
ie
ch
Te
Before Java 8: we use !=null for checking values.
g
rin
Sp
Before Java 8: Before java8 we don't have default methods in
java.Used abstract classes or implemented methods in all classes.
ie
ch
Before Java 8, coding was more complicated and required more lines
Te
of code, which made it harder to read and prone to errors.
So to avoid this repeated lines of coding and to make code more
readable and reliable java people introduced some additional features
in java8(jdk8) version.
g
Java 8 was introduced in 2014, which made a significant impact on the
way of writing code in java.
rin
As of now, Java 11 and Java 17 are among the most widely used
versions, with Java 8 still being popular in many legacy systems.
Sp
ie
3. New Date and Time API: Replaces the old Date and Calendar
classes with a more intuitive and comprehensive API (java.time
ch
package), improving date and time handling.
Te
4. Optional Class: Introduced to handle nullable values gracefully,
reducing NullPointerException risks.
g
rin
ie
ch
Te
g
Now let's dive in depth on each feature.
rin
1.Functional Interfaces:
ie
and helps the compiler ensure that the interface adheres to the
functional interface requirements (only one abstract method).
ch
Some key points to remember while creating
@FunctionalInterface Te
If you mark any Interface with @FunctionalInterface then you
must create only one abstract method inside it and any number
of default methods.
g
1.A FunctionalInterface can extend a regular interface that does
not have any abstract methods but it may contain default
rin
methods.
Sp
2.A FunctionalInterface can extend a regular interface
that does have one abstract method but the functional
interface should not contain any abstract method.
ie
ch
Te
3. We can extend a functional interface in java.
g
rin
Sp
How to implement functional interfaces.
To implement functional interfaces in Java, you can use lambda
expressions, method references, or traditional anonymous classes.
ie
Java 8 that allows you to implement the functional interfaces.
They make your code more readable and expressive, especially
ch
when working with collections, streams, and functional
programming constructs.
@FunctionalInterface
interface MyInterface {
Te
void myAbstractMethod();
}
System.out.println("Hello from
myAbstractMethod!");
};
implementation.myAbstractMethod();
// Call the implemented method
}
}
How to write a lambda expression for a functional interface…
Syntax:
ie
1.If method has two arguments and has to compute some
operation on variables in one line then you have to use () for
ch
arguments and no need of {} for method body.
2.If method has one argument and has to some compute some
operation on variable in one line then you don’t need to use () for
Te
arguments and no need of {} for method body.
ie
There are four main types of method references in Java 8:
1. Reference to a Static Method
2. Reference to an Instance Method of a Particular Object
ch
3. Reference to an Instance Method of an Arbitrary Object of a
Particular Type
4. Reference to a Constructor
Te
Example: Here I am taking an example for static method
reference and will explain how we are converting the lambda
expression into method reference.
g
Lambda Expression:
rin
ie
● Abstract method: T get()
● This represents a supplier of results, providing a value
without taking any input.
ch
● It is commonly used for lazy initialization or generating
values.
Example: Te
Supplier<Integer> randomNumberSupplier = () -> (int)
(Math.random() * 100);
int randomValue = randomNumberSupplier.get();
//Generates a random integer between 0 and 99
g
2. Consumer<T>:
● Abstract method: void accept(T t)
rin
Example:
Consumer<String> printMessage = message ->
System.out.println(message);
printMessage.accept("Hello, World!"); // Prints "Hello,
World!"
3. Function<T, R>:
● Abstract method: R apply(T t)
● This represents a function that accepts one argument and
produces a result.
● It is commonly used for mapping or transforming input to
output.
Example:
Function<Integer, String> intToString = num -> "Number: " +
ie
num;
String result = intToString.apply(42); // "Number: 42"
ch
4. Predicate<T>:
● Abstract method: boolean test(T t)
● It represents a predicate/condition, a boolean-valued
function that checks a condition on an input.
Te
● It is used for filtering or testing elements based on a
condition.
Example:
Predicate<Integer> isEven = num -> num % 2 == 0;
g
boolean result = isEven.test(8); // true
rin
5. UnaryOperator<T>:
● Abstract method: T apply(T t)
● This is a special case of the Function interface where the
input and output types are the same.
Sp
ie
int result = add.apply(3, 7); // 10
ch
7. Runnable:
new Thread(task).start();
g
rin
8.Comparator<T>
names.sort(lengthComparator);
2.Stream API:
The Java Stream API, introduced in Java 8, provides a powerful
way to process sequences of elements, making it easier to work
with collections and arrays in a functional style.
ie
element flows through the sequence of operations.
ch
Consider a water tank(List) on top of your home, we will
connect that water tank through a series of
pipes(intermediate methods) to our sink and at the end of
Te
the pipe we keep a tap(terminal methods) to control water
flow.
Characteristics:
ie
● Can be chained together.
● Operations are not executed immediately.
ch
● filter(Predicate<T> predicate): Filters elements based on
a condition.
Te
● map(Function<T, R> mapper): Transforms elements
using a function.
g
● distinct(): Removes duplicate elements.
rin
stream.
Terminal Methods:
● Produce a result or a side effect. They trigger the execution
of intermediate operations.
Characteristics:
ie
● forEach(Consumer<T> action): Performs an action for each
element.
● collect(Collector<T, A, R> collector): Collects elements into a
ch
collection.
● reduce(T identity, BinaryOperator<T> accumulator):
Aggregates elements into a single value.
● count(): Counts the number of elements.
Te
● anyMatch(Predicate<T> predicate): Checks if any element
matches a condition.
● allMatch(Predicate<T> predicate): Checks if all elements
match a condition.
g
● noneMatch(Predicate<T> predicate): Checks if no elements
match a condition.
rin
Sp
ie
ch
Te
g
rin
Sp
New Date and Time API:
ie
ch
Advantages: Te
● Immutable: Instances are immutable, enhancing thread
safety.
● Fluent API: Methods support method chaining.
● Comprehensive: Includes classes for various use cases
g
(e.g., Period, Duration).
● Time Zones: Better handling of time zones and offsets.
rin
Sp
Optional Class:
ie
How to Create an Optional:
ch
Useful for methods that explicitly return an empty result.
1.isPresent:
● Checks if a value is present.
if (optional.isPresent()) {
System.out.println(optional.get());
}
ie
2.ifPresent:
● Executes a lambda expression if a value is present.
ch
optional.ifPresent(value -> System.out.println(value));
3.orElse:
● Returns the value if present; otherwise, returns a default
Te
value.
4.orElseGet:
g
● Returns the value if present;
● otherwise, calls a supplier function to provide a value.
rin
5.orElseThrow:
● Returns the value if present;
Sp
6.get:
● Returns the value if present;
● throws NoSuchElementException if not.
ie
Advantages of Using Optional
ch
● Readability: Makes the code more readable and expresses
intent clearly.
● Functional Programming: Integrates well with Java's
Te
functional programming features, such as streams and
lambda expressions.
g
Stream methods:
rin
list.stream().map(String::length);
sorted: Sorts the elements of the stream.
list.stream().sorted();
list.stream().collect(Collectors.toList());
ie
forEach: Performs an action for each element.
ch
list.stream().forEach(System.out::println);
Te
distinct: Removes duplicate elements.
list.stream().distinct();
g
list.stream().limit(5);
Sp
list.stream().skip(3);
list.stream().reduce("", String::concat);
count: Counts the number of elements in the stream.
list.stream().count();
ie
list.stream().findFirst();
ch
findAny: Finds any element in the stream.
list.stream().findAny();
Te
anyMatch: Checks if any elements match a given condition.
g
list.stream().max(Comparator.naturalOrder());
list.stream().min(Comparator.naturalOrder());
ie
ch
Te
g
rin
Sp
Following are some of the famously asked Java8 Interview
Questions.
ie
Arrays.stream(arr).filter(i->i%2==0).forEach(System.out::println);
ch
2. Find First element in the list?
int arr[] = new int[]{9,10,15,8,49,25,98,32,10};
Te
Arrays.stream(arr).findFirst().ifPresent(System.out::println);
g
3. Find duplicates in the list?
rin
Arrays.stream(arr).filter(s->!set.add(s)).forEach(System.out::println);
Sp
forEach(System.out::println);
System.out.println("Min in array"+Arrays.stream(arr).min().getAsInt());
6. Find first non repeated character ?
String input = "swiss";
ie
Collectors.counting()));
ch
// Second pass: find the first character with count 1
.findFirst();
firstNonRepeatedChar.ifPresentOrElse(
g
c -> System.out.println("First non-repeated character: " + c),
);
Sp
Arrays.stream(arr).boxed().sorted(Collections.reverseOrder())
.forEach(System.out::println);
8. Perform cube on list elements and filter numbers greater than
50 ?
list.stream().map(i->i*i*i).filter(i->i>50).
collect(Collectors.toList()).forEach(System.out::println);
9. To sort an array and then convert the sorted array into Stream
ie
Arrays.parallelSort(arr);
Arrays.stream(arr).forEach(System.out::println);
ch
10. Find unique nos from the list ?
List list= Arrays.asList(11,22,33,44,11,22);
Te
System.out.println(list.stream()
.filter(x-> Collections.frequency(list,x)==1)
.collect(Collectors.toList()));
g
11. Optional Field usage ?
rin
class Nodes{
int id;
String tagName;
Sp
int count;
this.id=id;
this.tagName=tagName;
this.count=count;
this.id = id;
ie
public String getTagName() {
return tagName;
ch
public void setTagName(String tagName) {
this.tagName = tagName; Te
}
return count;
g
}
rin
this.count = count;
}
Sp
nodesList.add(node1);
nodesList.add(node2);
Optional.ofNullable(nodesList).
orElseGet(Collections::emptyList).
stream().filter(Objects::nonNull).
map(Nodes::getTagName).forEach(s->System.out.println("tag names
is:"+s));
ie
List<String> list1 = Arrays.asList("abc", "def", "xyz", "mno", "pqr",
ch
list1.stream().filter(s->set1.add(s)).forEach(System.out::println);
.map(String::toLowerCase)
g
.collect(Collectors.groupingBy(str -> str, HashMap::new,
Collectors.counting()));
rin
System.out.println(countMap);
Sp
System.out.println(Arrays.stream(arr1).
Collectors.summingInt(Integer::intValue)));
System.out.println("map::"+map1);
ie
16. Convert list to map
class Person{
ch
int id;
String name;
this.id=id;
this.name=name;
Te
}
g
public int getId() {
return id;
rin
this.id = id;
return name;
}
public void setName(String name) {
this.name = name;
listPerson.add(new Person(1,"vna"));
listPerson.add(new Person(2,"vid"));
ie
Map<Integer,Person1> mapPerson = listPerson.stream().
collect(Collectors.toMap(Person1::getId,Function.identity()));
ch
System.out.println(mapPerson);
filter(x->Collections.frequency(Arrays.asList(str.split(" ")),x)>=1).
g
collect(Collectors.groupingBy(Function.identity(),LinkedHashMap::new,
Collectors.counting()));
rin
System.out.println(mapStr);
Arrays.stream(str.split(" "))
.filter(x->Collections.frequency(Arrays.asList(str.split(" ")),x)>=1)
.collect(Collectors.groupingBy(Function.identity(),LinkedHashMap::new,Collector
s.counting())).entrySet().stream()
.thenComparing(Map.Entry.comparingByKey())).forEach(System.out::println);
19. Print Employee salary in Ascending order
class Employee{
ie
private long salary;
super();
ch
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
Te
}
}
rin
this.id = id;
}
Sp
return name;
this.name = name;
return age;
}
this.age = age;
return salary;
ie
public void setSalary(long salary) {
this.salary = salary;
ch
}
@Override
}
g
List < Employee > employees = new ArrayList < Employee > ();
List<Employee> resultAsc=employees.stream().
collect(Collectors.toList());
System.out.println("Ascending order::"+resultAsc);
System.out.println(employees.stream().
sorted(Comparator.comparingLong(Employee::getSalary)).
collect(Collectors.toList()));
List<Employee> resultDesc=employees.stream().
collect(Collectors.toList());
System.out.println("Descending order::"+resultDesc);
System.out.println(employees.stream().
ie
sorted(Comparator.comparingLong(Employee::getSalary).reversed()).
collect(Collectors.toList()));
ch
20 . Occurrence of elements ?
List<String> names = Arrays.asList("AA", "BB", "AA", "CC");
Te
HashMap<String,Long> map = names.stream().
collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new,
Collectors.counting()));
g
System.out.println(map);
rin
ie
.min(Comparator.comparing(String::length)).get();
System.out.println(shortestWord);
ch
24.Write a Java program to group a list of objects by a specific
field?
Order(customer="John", amount=100)
Te
Order(customer="Jane", amount=200)
Order(customer="John", amount=300)
.distinct()
.skip(1)
.findFirst()
.orElseThrow(NoSuchElementException::new);
ie
System.out.println("Sum: " + sum); // Output: Sum: 9
ch
27.Given a list of Optional<String>, write a Java 8 code snippet
to filter out the empty optionals and collect the values into a list?
List<Optional<String>> optionals = Arrays.asList(Optional.of("A"),
Optional.empty(), Optional.of("B"));
List<String> result = optionals.stream()
Te
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Optional.empty(), Optional.of("B"));
List<String> result = optionals.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
29.Write a Java 8 code snippet to calculate the sum of the
Sp