Java 8 Interface and use case
1 -Consumer interface
A Consumer is an in-build functional interface in the java.util.function package. we use consumers when we need to consume objects, the consumer takes an input value and returns nothing
Consumer interface consists of the following
void accept(T t,)
The BiConsumer interface consists of the following two functions:
void accept(T t, U u)
Only one difference b/w Consumer and BiConsumer argument
void accept(T value);
// We can pass consumer object in to forEach(Consumer<> con);
Consumer<Employee> c1 = s1->sop("Hello Boss"+s1.length());
c1.accept("Sanjay") o/p - Hello Boss 6
how to create consumer object
Consumer<Employee> c1 = s1->sop(s1.getName()+""+s1.getAge());
//use now c1 will pass
list.forEach(c1);
-------------BiConsumer--------
The BiConsumer interface consists of the following two functions:
void accept(T t, U u)
BiConsumer<Integer,Integer> biconsumer = (a,b)->sop("add =" +a+b);
biconsumer.accept(10,20) o/p= add=30
package com.logical.intface.functonal.consumer;
import java.util.List;
import java.util.function.Consumer;
import com.logical.application.java8.Employee;
import com.logical.application.java8.SetDataForEmployee;
public class ConsumerExample {
public static void main(String[] args) {
List<Employee> list = SetDataForEmployee.getEmployeeData();
// print all employee name
Consumer<Employee> c1 = s1 -> System.out.println(s1.getName());
// print all employee gender
Consumer<Employee> c2 = s1 -> System.out.println(s1.getGender());
// print all employee deparment
Consumer<Employee> c3 = s1 -> System.out.println(s1.getDepartment());
// list.forEach(c1);
// System.out.println("1st o/p=======================end");
// list.forEach(c2);
// System.out.println("2st o/p=======================end");
// list.forEach(c3);
// System.out.println("3st o/p=======================end");
// print name gender deparment
list.forEach(c1.andThen(c2).andThen(c3).andThen(c1));
// pass consumer inside forEachLoop
list.forEach(s -> {
if (s.getAge() > 40) {
c1.accept(s);
}
});
}
}
2-Predicate interface {Predicate<T> test(T t)}
it is a single argument function which is return true and false
Boolean test(T t)
BiPredicate interface {BiPredicate<T,U> test(T t,U u)}
it is two argument function which is return true and false
Boolean test(T t,U u)
it is only difference b/w BiPredicate and Predicate
Predicate<T>
Boolean test(T t)
Parameters:
t - the input argument
Returns:
true if the input argument matches the predicate, otherwise false
//
Prdecate<Integer> p1 = x->x>10;
sop(p1.test(20)) o/p False
BiPredicate interface
Boolean test(T t,U u)
for example when we can use BiPredicate
if i have employee list and I want to 2 condisan then
BiPredicate bx = (age,deparment)-> deparment==hr && age>20;
if i have employee list and I want to 2 condition then
BiPredicate bx = (age,deparment)-> deparment==hr && age>20;
Map and flatMap —
public class FlatmapExample {
public static void main(String[] args) {
List<User> user = SetDataForUser.setDataWithCity();
List<String> city = user.stream().flatMap(x -> x.getCity().stream()).sorted().collect(Collectors.toList());
System.out.println(city);
Map<String, List<String>> map = user.stream().collect(Collectors.toMap(User::getName, User::getCity));
System.out.println(map);
// use count()
Long l = user.stream().flatMap(x -> x.getCity().stream()).sorted().count();
System.out.println(l);
}
}
input
User user1 = new User(1, "D", "10", 10,Arrays.asList("delhi","agra"));
User user2 = new User(2, "C", "50", 50,Arrays.asList("mirzapur","allahabad"));
User user3 = new User(3, "A", "20",30,Arrays.asList("jaipur","lucknow"));
User user4 = new User(5, "B", "90",20,Arrays.asList("rajsthan","kolkata"));
List<User> list = Arrays.asList(user3, user2, user1, user4);
return list;
o/p
[agra, allahabad, delhi, jaipur, kolkata, lucknow, mirzapur, rajsthan]
{A=[jaipur, lucknow], B=[rajsthan, kolkata], C=[mirzapur, allahabad],
D=[delhi, agra]}
8
Java Comparator(Cutomize sorting)
package com.logical.intface.functonal.comprator;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import com.logical.application.java8.SetDataForUser;
import com.logical.application.java8.User;
public class CustomizeComprator {
public static void main(String[] args) {
List<User> user = SetDataForUser.setDataWithCity();
// Comparator with Lambda
Comparator<User> sortByUserName = Comparator.comparing(User::getName);
Comparator<User> sortByAge = Comparator.comparing(User::getAge);
Comparator<User> firstNamethenAgeComparator = (u1,u2) ->u1.getName()
.compareTo(u2.getAge());
List<User> list = user.stream().sorted(sortByUserName)
.collect(Collectors.toList());
List<User> list2 = user.stream()
.sorted(sortByUserName.thenComparing(sortByAge))
.collect(Collectors.toList());
List<User> list3 = user.stream().sorted(firstNamethenAgeComparator)
.collect(Collectors.toList());
System.out.println(list);
System.out.println(list2);
System.out.println(list3);
List<User> list4 = user.stream().
sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
//reversed method
List<User> list5 = user.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
System.out.println(list4);
System.out.println(list5);
}
}
0/p
[User [id=3, name=A, age=20, sal=30], User [id=5, name=B, age=90, sal=20], User [id=2, name=C, age=50, sal=50], User [id=1, name=D, age=10, sal=10], User [id=1, name=x, age=10, sal=10]]
[User [id=3, name=A, age=20, sal=30], User [id=5, name=B, age=90, sal=20], User [id=2, name=C, age=50, sal=50], User [id=1, name=D, age=10, sal=10], User [id=1, name=x, age=10, sal=10]]
[User [id=3, name=A, age=20, sal=30], User [id=2, name=C, age=50, sal=50], User [id=1, name=D, age=10, sal=10], User [id=5, name=B, age=90, sal=20], User [id=1, name=x, age=10, sal=10]]
Reduce — Reducing is the repeated process of combining all elements.
for example
Arrays.asList(1,2,3,4)
if you want sum of all element then we can use reduce()
int x =list.stream().reuce(0,(a,b)->a+b); o/p 10
int x =list.stream().reuce(0,(a,b)->a*b);
explain ==reuce(0,(a,b)->a+b)
0+1=1 (1 will store into place of 0)
1+2=3
3+3=6
6+4=10
I have a Employee list and if I want to sum of all employee sal then
package com.logical.intface.functonal;
import java.util.List;
import com.logical.application.java8.SetDataForUser;
import com.logical.application.java8.User;
public class ReduceMethod {
public static void main(String[] args) {
List<User> user = SetDataForUser.setDataWithCity();
int x=user.stream().map(User::getSal).reduce(0,(a,b)->a+b);
System.out.println(x);
}
Use filter+map+reduce
public class ReduceMethod {
public static void main(String[] args) {
List<User> user = SetDataForUser.setDataWithCity();
int x=user.stream().map(User::getSal).reduce(0,(a,b)->a+b);
System.out.println(x);
int op =user.stream().filter(a->a.getId()>3).map(User::getSal).reduce(0,(a,b)->a+b);
System.out.println(op);
OR
int opx =user.stream().filter(a->a.getId()>3)
.map(User::getSal).reduce(0,Integer::sum);
System.out.println(op);
}
o/p
20
20
max() and reduce() and same way we can use min() also
we can get maximum value from list
we can get min value from list
// -------------------------------------
List<Integer> list = Arrays.asList(1, 8, 9, 6, 5);
// how find max from list
int value = list.stream().max(Integer::compareTo).get();
System.out.println(value);
int value2 = list.stream().reduce(0, (a, b) -> a > b ? a : b);
System.out.println(value2);
o/p for both 9
limit(), skip()
from list if I want only 5 no then we can use limit (first five get)
from list if I left only 5 and need rest element then use skip (first five left)
List<Integer> value4 = list.stream().limit(3).collect(Collectors.toList());
System.out.println(value4);
List<Integer> value5= list.stream().skip(3).collect(Collectors.toList());
System.out.println(value5);
o/p
[1, 8, 9]
[6, 5]
findFirst() and FindAny() — -
findFirst()
method returns the first element of a stream
findAny()
method returns any element of the stream
Optional<String> person = people.stream()
.filter(x -> x.length() > 4)
.findFirst();
Optional<String> person2 = people.stream()
.filter(x -> x.length() > 4)
.parallel()
.findAny();
Stream Aggregate Functions
Use a Parallel Stream in Java
public class ParallelStreamExample {
public static void main(String[] args) {
System.out.println("Sum Sequential: " + sumSequentialStream());
System.out.println("Sum Parallel: " + sumParallelStream());
}
public static int sumSequentialStream(){
return IntStream.rangeClosed(0,50000).sum();
}
public static int sumParallelStream(){
return IntStream.rangeClosed(0,50000).parallel().sum();
}
}
-----------------------------performance
package com.modernjava.parallelstream;
import java.util.function.Supplier;
import java.util.stream.IntStream;
public class StreamPerformanceExample {
public static void main(String[] args) {
int loop = 20;
long result = measurePerformance(StreamPerformanceExample::sumSequentialStream,loop);
System.out.println("Time Taken to process sum in sequential: "
+ result + "in msecs");
result = measurePerformance(StreamPerformanceExample::sumParallelStream,loop);
System.out.println("Time Takes to process sum in Parallel: " + result + " in msecs");
}
public static long measurePerformance (Supplier<Integer> supplier, int numberOfTimes){
long startTime= System.currentTimeMillis();
for (int i=0;i<numberOfTimes;i++)
supplier.get();
return System.currentTimeMillis() - startTime;
}
public static int sumSequentialStream(){
return IntStream.rangeClosed(0,50000).sum();
}
public static int sumParallelStream(){
return IntStream.rangeClosed(0,50000).parallel().sum();
}
}
Java 8 Optional Class
package com.modernjava.optional;
import java.util.Arrays;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
// Integer[] numbers = new Integer[10];
// int number = numbers[1].intValue();
// System.out.println("number = " + number);
Optional<String> optionalString = Optional.of("Hello World");
System.out.println("optionalString = " + optionalString);
System.out.println("getWords:" + getWords());
}
public static Optional<String> getWords() {
String[] words = new String[10];
Optional<String> optionalS = Optional.ofNullable(words[1]);
if (optionalS.isPresent())
return optionalS;
else
return Optional.empty();
}
}
---------------------
package com.modernjava.optional;
import java.util.Optional;
public class OptionalOrElseThrowExample {
public static void main(String[] args) {
//orElse
Integer[] numbers = new Integer[10];
numbers[0] = 1;
Optional<Integer> number = Optional.ofNullable(numbers[0]);
int result = number.orElse(-1);
System.out.println("result = " + result);
//orElseGet
result = number.orElseGet(() -> -1);
System.out.println("result - orElseGet = " + result);
//orElseThrow
try {
result = number.orElseThrow(Exception::new);
System.out.println("result orElseThrow = " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java 8 Collectors Oprations
In Java 8, the Collectors
class is a utility that provides various operations to transform data into collections or other results. It's primarily used with Java 8 Streams API to perform reduction operations like converting elements into a List
, Set
, Map
, or even computing aggregations like counting()
, summing()
, and more. Below are some common Collectors
operations:
1. toList()
This collector accumulates elements into a List
.
List<String> names = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
2. toSet()
This collects elements into a Set
, ensuring uniqueness.
Set<String> namesSet = people.stream()
.map(Person::getName)
.collect(Collectors.toSet());
3. toMap()
This collects elements into a Map
by defining keys and values. You can also provide a merge function to handle duplicate keys.
Map<Integer, String> idToNameMap = people.stream()
.collect(Collectors.toMap(Person::getId, Person::getName));
4. counting()
This returns the count of elements in the stream.
long count = people.stream()
.collect(Collectors.counting());
5. joining()
This concatenates the elements into a single String
, with optional delimiter, prefix, and suffix.
- Without delimiter:
String joinedNames = people.stream()
.map(Person::getName)
.collect(Collectors.joining());
- With delimiter:
String joinedNamesWithComma = people.stream()
.map(Person::getName)
.collect(Collectors.joining(", "));
6. summingInt(), summingDouble(), summingLong()
These collectors sum values of elements for numeric data.
int totalAge = people.stream()
.collect(Collectors.summingInt(Person::getAge));
7. averagingInt(), averagingDouble(), averagingLong()
These calculate the average of the numeric values.
double averageAge = people.stream()
.collect(Collectors.averagingInt(Person::getAge));
8. groupingBy()
This groups elements by a classifier function. The result is a Map
where the keys are the values of the classifier and the values are lists of items.
Map<String, List<Person>> peopleByCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
9. partitioningBy()
This partitions elements into two groups based on a predicate. It returns a Map
with Boolean keys.
Map<Boolean, List<Person>> partitionedByAge = people.stream()
.collect(Collectors.partitioningBy(person -> person.getAge() > 30));
10. maxBy(), minBy()
These return the maximum or minimum element based on a comparator.
- maxBy:
Optional<Person> oldestPerson = people.stream()
.collect(Collectors.maxBy(Comparator.comparingInt(Person::getAge)));
- minBy:
Optional<Person> youngestPerson = people.stream()
.collect(Collectors.minBy(Comparator.comparingInt(Person::getAge)));
11. reducing()
This is a more general form of reduction that allows you to perform custom reductions.
int totalAge = people.stream()
.collect(Collectors.reducing(0, Person::getAge, Integer::sum));
12. mapping()
This collector first applies a mapping function before collecting the elements. Often used in combination with groupingBy
or other collectors.
Map<String, List<String>> namesByCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity,
Collectors.mapping(Person::getName, Collectors.toList())))