The new features and changes in OpenJDK 15:
Best Practices :
- Use thread-safe date classes instead of SimpleDateFormat prefer DateTimeFormatter, OffsetDateTime, ZonedDateTime, LocalDateTime, LocalDate, and LocalTime.
Java 8 Garbage Collection Improvement
Turn on the -XX:+UseStringDeduplication
JVM argument while using G1 garbage collector. This optimizes the heap memory by removing duplicate String values to a single char[] array. This option is introduced in Java 8 u 20.
Functional Interface
A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This “single” method may take the form of multiple abstract methods with override-equivalent signatures inherited from super interfaces; in this case, the inherited methods logically represent a single method.
Note that if you declare an abstract method overriding one of a public method from the Object’s class it doesn’t count, because any implementation of this interface will have an implementation of those methods through at least the Object’s class.
Default Method
Java 8 introduces default method so that Collection interface can have a default implementation of forEach method without requiring the classes implementing this interface to implement the same.
Optional
java.util.Optional is a final class.
We would normally create such an object and wrap it in an Optional object just like we did with String.
Person person = new Person(); Optional personOptional = Optional.of(person);Collections
Classes in the new
java.util.stream
packageImplementations of
Collector
interface that implement various useful reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc.The following are examples of using the predefined collectors to perform common mutable reduction tasks:
Stream is an Interface.
Stream ==> A sequence of elements supporting sequential and parallel aggregate operations.The JDK’s standard implementation of
Stream
is the internal classjava.util.stream.ReferencePipeline
, you cannot instantiate it directly.Instead you can use
java.util.stream.Stream.builder()
,java.util.stream.StreamSupport.stream(Spliterator, boolean)
and various1, 2 other static factory methods to create an instance of the default implementation.Stream Iterator vs Spliterator
stream map vs flatmap
// Accumulate names into a List
List list = people
.stream()
.map(Person::getName)
.collect(Collectors.toList());
// Accumulate names into a TreeSet
Set set = people
.stream()
.map(Person::getName)
.collect(Collectors.toCollection(TreeSet::new));
// Convert elements to strings and concatenate them,
// separated by commas
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// Compute sum of salaries of employee
int total = employees.stream()
.collect(Collectors.summingInt
(Employee::getSalary)));
// Group employees by department
Map<Department, List> byDept
= employees.stream()
.collect(Collectors.groupingBy
(Employee::getDepartment));
// Compute sum of salaries by department
Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy
(Employee::getDepartment,
Collectors.summingInt
(Employee::getSalary)));
// Partition students into passing and failing
Map<Boolean, List> passingFailing =
students.stream()
.collect(Collectors.partitioningBy
(s -> s.getGrade() >= PASS_THRESHOLD));
LocalDate, LocalTime and Clock
CompletableFuture
java.util.function Package
The java.util.function package in Java 8 contains many builtin functional interfaces like
- Predicate: The Predicate interface has an abstract method test which gives a Boolean value as a result for the specified argument. Its prototype is
public Predicate { public boolean test(T t); }
import java.util.function.Predicate;
public class PredicateInterfaceExample2 {
public static void main(String[] args)
{
Predicate<Integer> greaterThanTen = (i) -> i > 10;// Creating predicate
Predicate<Integer> lowerThanTwenty = (i) -> i < 20;
boolean result = greaterThanTen.and(lowerThanTwenty).test(15);
System.out.println(result);// Calling Predicate method
boolean result2 = greaterThanTen.and(lowerThanTwenty).negate().test(15);
System.out.println(result2);
}
} - Supplier is functional interface which does not take any argument and produces result of type T.
-
import java.util.function.Supplier;public class Java8SupplierExample {public static void main(String[] args) {Supplier studentSupplier = () -> new Student(1, “Arpit”, “M”, 19);Student student = studentSupplier.get();System.out.println(student);}}
-
- BinaryOperator: The BinaryOperator interface has an abstract method apply which takes two argument and returns a result of same type. Its prototype is
public interface BinaryOperator { public T apply(T x, T y); }
- Function: The Function interface has an abstract method apply which takes argument of type T and returns a result of type R. Its prototype is
public interface Function { public R apply(T t); }
- The functional interfaces in this package follow an extensible naming convention, as follows:
- There are several basic function shapes, including
java.util.function.Function
(unary function fromT
toR
),java.util.function.Consumer
(unary function fromT
tovoid
),java.util.function.Predicate
(unary function fromT
toboolean
), andjava.util.function.Supplier
(nilary function toR
). - Function shapes have a natural arity based on how they are most commonly used. The basic shapes can be modified by an arity prefix to indicate a different arity, such as
java.util.function.BiFunction
(binary function fromT
andU
toR
). - There are additional derived function shapes which extend the basic function shapes, including
java.util.function.UnaryOperator
(extendsFunction
) andjava.util.function.BinaryOperator
(extendsBiFunction
). - Type parameters of functional interfaces can be specialized to primitives with additional type prefixes. To specialize the return type for a type that has both generic return type and generic arguments, we prefix
ToXxx
, as injava.util.function.ToIntFunction
. Otherwise, type arguments are specialized left-to-right, as injava.util.function.DoubleConsumer
orjava.util.function.ObjIntConsumer
. (The type prefixObj
is used to indicate that we don’t want to specialize this parameter, but want to move on to the next parameter, as injava.util.function.ObjIntConsumer
.) These schemes can be combined, as inIntToDoubleFunction
. - If there are specialization prefixes for all arguments, the arity prefix may be left out (as in
java.util.function.ObjIntConsumer
).
- There are several basic function shapes, including
Map vs FlatMap
Parallel Stream vs Sequential Stream
Java 7
Diamond Operator
Car myCar =
new
Car<>();