Candidates might face platform specific questions in the interviews of different companies. This article is intended to serve as a starting point for java 8 related interview questions. However, please note that, the best way to have a good command of technical platforms is to practice.
With each major release of the language, java team releases important features. Let's us take a look at the most significant ones with java 8:
- Functional Programming Features; functional interfaces, lambda expressions
- Default and Static method in Intefaces
- Stream API and bulk data operations,
- Concurrency API improvements; ConcurrentHashMap, CompletableFutures, improvements in executors
- Nashorn, Javascript Engine
- ...
Lambda expressions are anonymous functions (functions without name), which may or may not accept arguments, and executes a code block. The snippets below are all valid lambda expressions:
() -> System.out.println("Hello world")
(String name) -> System.out.println("Hello name " + name)
//Types of variables are deduced from the context
(var1, var2) -> System.out.println("variable one: " + var1 + "variable 2: " + var2)
BiFunction<Integer, Integer, Integer> sum = (Integer v1, Integer v2) -> {
return v1 + v2;
};
What is method reference? What kind of method references exist in Java?
Java 8 provides method reference construct to help developers to reuse existing code in a more readable fashion. By this feature we can address the existing implementation directly, instead of addressing the functionality in a lambda, which might get cumbersome depending on the complexity of the code. A method reference is expressed with a semicolon + method name which is follows an object or a class name.
List<SomeComparableObject> objects = Arrays.asList( o1, o2, o3, ...);
ojbects.sort((SomeComparableObject o1, SomeComparableObject o2) -> o1.compareTo(o2));
// or with method reference
objects.sort(SomeComparableObject::compareTo);
There are three different kinds of method references in Java:
- Static method references: As the name suggests, these method references are used for referencing static methods in a class.
static class SomeIntegerHelperClass {
static Integer square(Integer i) {
return i * i;
}
}
private void staticMethodReference() {
List < Integer > listOfIntegers = Arrays.asList(1, -2, 3, 4);
//With lambda
listOfIntegers.stream().map((Integer i) -> SomeIntegerHelperClass.square(i));
//Static method reference
listOfIntegers.stream().map(SomeIntegerHelperClass::square);
}
- Bound instance method reference: This type is a reference to the instance method of an object.
static class ValueClass {
Integer value;
public ValueClass(Integer value) {
this.value = value;
}
}
static class Operator {
public void printQube(ValueClass valueClass) {
System.out.println(valueClass.value * valueClass.value * valueClass.value);
}
}
void consume(ValueClass valueClass, Consumer < ValueClass > behaviour) {
behaviour.accept(valueClass);
}
void someMethod() {
ValueClass instance = new ValueClass(3);
Operator operator = new Operator();
//With anonymous class
this.consume(instance, new Consumer < ValueClass > () {
@Override
public void accept(ValueClass valueClass) {
operator.printQube(valueClass);
}
});
//With lambda
this.consume(instance, i -> operator.printQube(i));
//With bound method reference
this.consume(instance, operator::printQube);
}
- Unbound instance method reference:
static class ValueClass {
Integer value;
public ValueClass(Integer value) {
this.value = value;
}
public void printMySquare() {
System.out.println(this.value * this.value);
}
}
void consume(ValueClass valueClass) {
List < ValueClass > values = Arrays.asList(new ValueClass(2), new ValueClass(3));
//With lambda
values.forEach(v -> v.printMySquare());
//With unbound method reference
values.forEach(ValueClass::printMySquare);
}
What is a functional interface?
Functional interfaces are the interfaces with only one abstract method. Note that, the method exposed by the interface is abstract and provides no default implementation.
@FunctionalInterface annotation is usually used as a marker annotation to denote functional interfaces.
Java already provides built-in functional interfaces like:
- Predicate,
- BiPredicate,
- Function,
- BiFunction,
- Runnable,
- Consumer,
- BiConsumer,
- BinaryOperator,
- UnaryOperator,
- Supplier,
- Callable,
However, you are not restricted to use only these builtin interfaces. You can create your own functional interfaces depending on your need.
Is @FunctionalInterface mandatory to define a Functional Interface?
No, it's just a marker interface. Any interface which has one and only one abstract method can be used as a functional interface regardless they are marked with @FunctionalInterface annotation or not.
Nevertheless, if we use @FunctionalInterface annotation to mark an interface, then java compiler checks whether that interface has only one abstract method.
Interfaces
What is a default method? Where can we define default methods? When do we use default methods?
Default method is a concrete method implementation provided in an interface. Default methods can be used with two different purposes:
- To provide an additional functionality to an already existing interface without breaking the backward compatibility. For instance, prior to Java 8 the Collection interface did not have a forEach method. If there were no default method support, then the classes would have been broken by the new version of the interface or this method would have to be implemented by all of the classes. Now with a default implementation, these classes can remain unchanged and can provide the functionality via the default implementation.
- To provide a default behavior for the implementing classes so that we do not have to implement a method each time we implement the interface, unless we would like to handle behavior in a different manner.
Is it ok to use default methods in functional interfaces?
Definitely yes, the core restriction for functional interfaces is to have one and only one abstract method declaration within the implementation. Having default methods in an implementation does not break this rule.
What happens if a class implements two interfaces which have default methods with same signatures and names?
In this case, compiler throws a compile time error. Such a class must provide its own implementation of the corresponding default methods.
Optional
What is Optional?
Optional is a class provided by java 8 to encapsulate values that may or may not exists. Before the introduction of Optional, we were adding boilerplate code, for the sake of defensive programming, to check if a value returned by a method call is null or not. Now with the introduction of Optional, a method can explicitly declare whether it's possible to get an empty (null) result from a call by declaring the return type as Optional<SomeClass>, so that consumers of this method can act accordingly without referring to the documentation of that method or without adding boilerplate code to be defensive.
Comments
Post a Comment