Skip to main content

Posts

Showing posts with the label Java 8

Java 8 - default and static methods in interfaces

Java 8 introduced default and static methods in interfaces. These features allow us to add new functionality in the interfaces without breaking the existing contract for implementing classes. How do we define default and static methods? Default method has default and static method has static keyword in the method signature. public interface InterfaceA { double someMethodA(); default double someDefaultMethodB() { // some default implementation } static void someStaticMethodC() { //helper method implementation } Few important points for default method You can inherit the default method. You can redeclare the default method essentially making it abstract . You can redefine the default method (equivalent to overriding). Why do we need default and static methods? Consider an existing Expression interface with existing implementation like ConstantExpression , BinaryExpression , DivisionExpression and so on. Now, you want to add new functionalit

Java 8 - Method references

This article is in continuation to my other posts on Functional Interfaces , static and default methods and Lambda expressions . Method references are the special form of Lambda expression . When your lambda expression are doing nothing other than invoking existing behaviour (method), you can achieve same by referring it by name. :: is used to refer to a method. Method type arguments are infered by JRE at runtime from context it is defined. Types of method references Static method reference Instance method reference of particular object Instance method reference of an arbitrary object of particular type Constructor reference Static method reference When you refer static method of Containing class. e.g. ClassName::someStaticMethodName class MethodReferenceExample { public static int compareByAge(Employee first, Employee second) { return Integer.compare(first.age, second.age); } } Comparator compareByAge = MethodReferenceExample::compareByAge; Instanc

Java 8 - Streams in Action

In this post, we will cover following topics. What are Streams? What is a pipeline? Key points to remember for Streams. How to create Streams? What are Streams? Java 8 introduced new package java.util.stream which contains classes to perform SQL-like operations on elements. Stream is a sequence of elements on which you can perform aggregate operations (reduction, filtering, mapping, average, min, max etc.). It is not a data structure that stores elements like collection but carries values often lazily computed from source through pipeline . What is a pipeline? A pipeline is sequence of aggregate (reduction and terminal) operations on the source. It has following components. A source: Collections, Generator Function, array, I/O channel etc. zero or more intermediate operations: filter, map, sequential, sorted, distinct, limit, flatMap, parallel etc. Intermediate operations returns/produces stream. a termination operation: forEach, reduction, noneMatch, allMatch, c

Java 8 - Aggregate operations on Streams

This post is in continuation with my earlier posts on Streams . In this post we will discuss about aggregate operations on Streams. Aggregate operations on Streams You can perform intermediate and terminal operations on Streams. Intermediate operations result in a new stream and are lazily evaluated and will start when terminal operation is called. persons.stream().filter(p -> p.getGender() == Gender.MALE).forEach(System.out::println); In the snippet above, filter() doesn't start filtering immediately but create a new stream. It will only start when terminal operation is called and in above case when forEach() . Intermediate operations There are many intermediate operations that you can perform on Streams. Some of them are filter() , distinct() , sorted() , limit() , parallel() , sequential , map() , flatMap . filter() operation This takes Predicate functional interface as argument and the output stream of this operation will have only those elements which pass th

Java 8 - Lambda expressions

In this post, we will cover following topics. What are Lambda expressions? Syntax for Lambda expression. How to define no parameter Lambda expression? How to define single/ multi parameter Lambda expression? How to return value from Lambda expression? Accessing local variables in Lambda expression. Target typing in Lambda expression. What are Lambda expressions? Lambda expressions are the first step of Java towards functional programming. Lambda expressions enable us to treat functionality as method arguments, express instances of single-method classes more compactly. Syntax for Lambda expression Lambda has three parts: comma separated list of formal parameters enclosed in parenthesis. arrow token -> . and, body of expression (which may or may not return value). (param) -> { System.out.println(param); } Lambda expression can only be used where the type they are matched are functional interfaces . How to define no parameter Lambda expression? If the la

Java 8 - What are functional interfaces in Java?

Java 8 reincarnated SAM interfaces and termed them Functional interfaces. Functional interfaces have single abstract method and are eligible to be represented with Lambda expression . @FunctionalInterface annotation is introduced in Java 8 to mark an interface as functional. It ensures at compile-time that it has only single abstract method, otherwise it will throw compilation error. Let's define a functional interface. @FunctionalInterface public interface Spec<T> { boolean isSatisfiedBy(T t); } Functional interfaces can have default and static methods in them and still remains functional interface. @FunctionalInterface public interface Spec<T> { boolean isSatisfiedBy(T t); default Spec<T> not() { return (t) -> !isSatisfiedBy(t); } default Spec<T> and(Spec<T> other) { return (t) -> isSatisfiedBy(t) && other.isSatisfiedBy(t); } default Spec<T> or(Spec<T> other) { return (t) -> isSa

Java 8 - Iterating collections and maps with #forEach, Consumer and BiConsumer

Iterating Collections API Java 8 introduced new way of iterating Collections API. It is retrofitted to support #forEach method which accepts Consumer in case of Collection and BiConsumer in case of Map . Consumer Java 8 added introduced new package java.util.function which also includes Consumer interface. It represents the operation which accepts one argument and returns no result. Before Java 8, you would have used for loop, extended for loop and/ or Iterator to iterate over Collections . List < Employee > employees = EmployeeStub . getEmployees(); Iterator < Employee > employeeItr = employees . iterator(); Employee employee; while (employeeItr . hasNext()) { employee = employeeItr . next(); System . out . println(employee); } In Java 8, you can write Consumer and pass the reference to #forEach method for performing operation on every item of Collection . // fetch employees from Stub List < Employee > employees = EmployeeStub . getEmplo

Java 8 - Filtering with Predicates

In this post, we will cover following items. What is java.util.function.Predicate? How to filter data with Predicates? Predicate chaining. Java 8 introduced many new features like Streaming API, Lambdas , Functional interfaces , default methods in interfaces and many more. Today, we will discuss about Predicate interface added in java.util.function package and its usage in filtering in-memory data. What is java.util.function.Predicate? Predicate is like a condition checker, which accepts one argument of type T and return the boolean value. It's a functional interface with functional method test(Object) . Here, Object is typed. @FunctionalInterface interface Predicate < T > { public boolean test ( T t ); } How we can filter data with Predicates? Consider we have Collection of employees and we want to filter them based on age, sex, salary and/ or with any other combinations. We can do that with Predicate . Let's understand this with one short