Monday, September 30, 2019

Java 8 – Map’s computeIfAbsent, computeIfPresent, getOrDefault methods

In this tutorial blog, we will be looking at the enhancements introduced in java.util.Map interface in Java 8. We will first quickly understand what are multi-value maps. Next we will create a multi-value map which will serve as the base problem set for explaining the new Map methods. We will first see the working of Java 8’s new Map.forEach() and Map.replaceAll() methods. Next, we will understand the new default methods introduced in Java 8 which simplify using multi-value maps. These methods are Map.computeIfAbsent(), Map.computeIfPresent() and Map.getOrDefault() methods.

What is a multi-value map

A multi-value map is a normal instance of java.util.Map. The only difference is that instead of having a ‘single’ value corresponding to each key, a multi-value map instead has a ‘collection’ such as a List or a Set as the value stored against each key.

Multi-value map with ArrayList as value
A good example of a use-case for a multi-value map would be of the hash table used to store hash keys and corresponding values. In a hash table, there exists a mappping between a hash value(key) and entries stored in a bucket (value) stored corresponding to it. A hash table is thus essentially a multi-value map.

Defining the data set/multi-value Map for this tutorial

Java 8 code defining a multi-value map
package com.javabrahman.java8;
public class Employee {
  private String name;
  private Integer age;
  private Double salary;
  public Employee(String name, Integer age, Double salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
  }
  public String toString(){
    DecimalFormat dformat = new DecimalFormat(".##");
    return "Employee Name:"+this.name
        +"  Age:"+this.age
        +"  Salary:"+dformat.format(this.salary);
  }
//getters and setters for name, age and salary go here
//standard equals() and hashcode() code go here
}
//MultiValueMapsExample.java
package com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.*;
public class MultiValueMapsExample {
  static Map<Integer, List<Employee>> employeeDOJMap = new HashMap<>();
 
  public static void main(String args[]) {

    List<Employee> list2014 = Arrays.asList(
        new Employee("Deborah Sprightly", 29, 9000.00));
    employeeDOJMap.put(2014, list2014);
    List<Employee> list2015 = Arrays.asList(
        new Employee("Tom Jones", 45, 7000.00),
        new Employee("Harry Major", 25, 10000.00));
    employeeDOJMap.put(2015, list2015);
    List<Employee> list2016 = Arrays.asList(
        new Employee("Ethan Hardy", 65, 8000.00),
        new Employee("Nancy Smith", 22, 12000.00));
    employeeDOJMap.put(2016, list2016);
  }
}

Java 8’s new Map.forEach() and Map.replaceAll() methods

Let us start by quickly going through the relatively simpler methods introduced in Map interface in Java 8- Map.forEach() and Map.replaceAll().

Map.forEach()

Map.forEach() method is defined as –

default void forEach(BiConsumer<? super K, ? super V> action)
Where,
     – action is the only parameter and is an instance of a BiConsumer functional interface, and,
     – method applies the logic provided via action to all the entries in the map as it ‘consumes’ them.



What is a BiConsumerWhat is a BiConsumer

java.util.function.BiConsumer is a functional interface, and is a two-arity specialization of a Consumer Functional Interface. I.e. it accepts two inputs as arguments and does not return any output.

Map.replaceAll()

Map.replaceAll() method is defined as –

default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
Where,
     – function is the only parameter and is an instance of a BiFunction Functional Interface, and,
     – the method applies the logic provided via function to all the values in the map and transforms them inside the map itself.

What is a BiFunctionWhat is a BiFunction

java.util.function.BiFunction is a functional interface, and is a two-arity specialization of Function. I.e. it accepts two inputs as arguments and returns a result after performing a computation with the input.

Let us now see the Map.forEach() and Map.replaceAll() methods in action –

Java 8 code showing Map.forEach() and Map.replaceAll() methods
System.out.println("Using Map.forEach to print the Employee in employeeDOJMap multi-value map\n");
employeeDOJMap.forEach((year,empList)->System.out.println(year+"-->" +empList));

System.out.println("\nCAPITALIZED Employee Names using Map.replaceAll()");
employeeDOJMap.replaceAll((year, empList) -> {
empList.replaceAll(emp -> {
    emp.setName(emp.getName().toUpperCase());
    return emp;
  });
  return empList;
});

employeeDOJMap.forEach((year, empList)-> System.out.println(year+"-->"+empList));


 OUTPUT of the above code


Using Map.forEach to print the Employee in employeeDOJMap multi-value map –
2016–>[Employee Name: Ethan Hardy  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2014–>[Employee Name: Deborah Sprightly  Age: 29  Salary: 9000.0]
2015–>[Employee Name: Tom Jones  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]

CAPITALIZED Employee Names using Map.replaceAll()
2016–>[Employee Name: ETHAN HARDY  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2014–>[Employee Name: DEBORAH SPRIGHTLY  Age: 29  Salary: 9000.0]
2015–>[Employee Name: TOM JONES  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]

Java 8’s Map.computeIfAbsent() method

As we learnt earlier, a multi-value map stores a collection of values for each key. Lets say we are adding a [key,value] entry to a multi-value map and the key we are adding is not present in the map. This would require for us to check for this probability before insertion and if the key is not present then we will have to instantiate a fresh collection instance as the value for this new key. Only then can we store the value against the key. Also, this check will need to be performed on every insert that we do.

Map.computeIfAbsent() takes away exactly this overhead of writing the multiple line code for such a check by squeezing it into a simple one line code. Map.computeIfAbsent() method is defined as –

default V computeIfAbsent(K key,Function<? super K,? extends V>mappingFunction)
Where,
     – key is the first parameter which is the key of the multi-value map.
     – function is an instance of java.util.function.Function. It computes and returns the value which is to be used when the key is new i.e. does not have a collection instantiated in the case of a multi-value map.

Have a look at the code sample below to understand the difference in code when using Java 7 versus Java 8’s computeIfAbsent() method. The red code is Java 7 way of checking and instantiating before all insertions. The green code is Java 8 way of doing the same thing using Map.computeIfAbsent() method.

Java 8 code to show usage of Map.computeIfAbsent() method

System.out.println("\nJava 7 way of adding a new key(2017) in a multi-value map\n");
List empList2017 = employeeDOJMap.get(2017);
if (empList2017 == null) {
  empList2017 = new ArrayList<>();
}
empList2017.add(new Employee("Tom Newman", 45, 12000.00));
employeeDOJMap.put(2017, empList2017);
employeeDOJMap.forEach((year,empList)-> System.out.println(year+"-->"+empList));
System.out.println("\nUsing Map.computeIfAbsent() to add a new key(2018) in a multi-value map\n");
employeeDOJMap.computeIfAbsent(2018,empList -> new ArrayList<>())
              .add(new Employee("Dick Newman", 35, 10000.00));
employeeDOJMap.forEach((year,empList)-> System.out.println(year+"-->"+empList));


 OUTPUT of the above code


Java 7 way of adding a new key(2017) in a multi-value map
2016–>[Employee Name: Ethan Hardy  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2017–>[Employee Name: Tom Newman  Age: 45  Salary: 12000.0]
2014–>[Employee Name: Deborah Sprightly  Age: 29  Salary: 9000.0]
2015–>[Employee Name: Tom Jones  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]
Using Map.computeIfAbsent() to add a new key(2018) in a multi-value map
2016–>[Employee Name: Ethan Hardy  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2017–>[Employee Name: Tom Newman  Age: 45  Salary: 12000.0]
2018–>[Employee Name: Dick Newman  Age: 35  Salary: 10000.0]
2014–>[Employee Name: Deborah Sprightly  Age: 29  Salary: 9000.0]
2015–>[Employee Name: Tom Jones  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]

Java 8’s new Map.computeIfPresent() method


When working with multi-value maps, there are scenarios when while deleting a [key,value] pair, we might be removing the last/only value in the collection stored as the value for that key. In such cases, after removing the value from the collection, we would want to release the memory occupied by that the empty collection by removing that key from the multi-value map itself. This would require us to check after ‘every’ removal whether the value being removed is the last value for that key, and if so, remove the key from the multi-value map.

Map.computeIfPresent() takes away exactly this overhead of checking after every removal by reducing it to a simple one-line code. Map.computeIfPresent() method is defined as –

default V computeIfPresent(K key,BiFunction<? super K,? super V,? extends V>remappingFunction)
Where,
     – key is the first parameter which is the key of the multi-value map.
     – remappingFunction is an instance of a BiFunction. It computes and returns a value. In case of multi-value maps, the outcome of the key’s collection is decided based the value returned by this function. I.e. whether to keep the collection(if the collection is returned) or delete the collection(if a null value is returned).

To understand the usage of computeIfPresent() method better, let us have a look at the code sample below to understand the difference in code when using Java 7 versus Java 8’s computeIfPresent() method. As we did for the previous method, we will use color coding to differentiate between the Java 7 and Java 8 code. The red code is Java 7 way of checking and removing a key after every removal from the map. The green code is Java 8 way of doing the same thing using Map.computeIfPresent() method.

Java 8 code to show usage of Map.computeIfPresent() method
System.out.println("\nJava 7 way of removing a key(2017) in a multi-value map for which no entry exists\n");
List empListDel = employeeDOJMap.get(2017);
empListDel.removeIf(employee -> employee.getName().equals("Tom Newman"));
if (empListDel.size() == 0) {
  employeeDOJMap.remove(2017);
}
employeeDOJMap.forEach((year, empList)-> System.out.println(year+"-->"+empList));
System.out.println("\nUsing Map.computeIfPresent() to remove a key(2018) for which no entry exists\n");
employeeDOJMap.computeIfPresent(2018, (year, empList) -> empList.removeIf(employee -> employee.getName().equals("Dick Newman")) && empList.size() == 0 ? null : empList);
employeeDOJMap.forEach((year, empList)-> System.out.println(year+"-->"+empList));


 OUTPUT of the above code


Java 7 way of removing a key(2017) in a multi-value map for which no entry exists
2016–>[Employee Name: Ethan Hardy  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2018–>[Employee Name: Dick Newman  Age: 35  Salary: 10000.0]
2014–>[Employee Name: Deborah Sprightly  Age: 29  Salary: 9000.0]
2015–>[Employee Name: Tom Jones  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]
Using Map.computeIfPresent() to remove a key(2018) for which no entry exists
2016–>[Employee Name: Ethan Hardy  Age: 65  Salary: 8000.0, Employee Name: Nancy Smith  Age: 22  Salary: 12000.0]
2014–>[Employee Name: Deborah Sprightly  Age: 29  Salary: 9000.0]
2015–>[Employee Name: Tom Jones  Age: 45  Salary: 7000.0, Employee Name: Harry Major  Age:25  Salary: 10000.0]


Map.getOrDefault() method


Map.getOrDefault() method has been designed for scenarios where the value returned for a given key might be null i.e. the given key is not present in the map. In case of multi-value maps, it gives the programmer a utility to avoid NullPointerException at runtime by instantiating a new collection instance and returning it in case the key is not present and a null-value would otherwise have been returned.

Map.getOrDefault() is defined as follows –

default V getOrDefault(Object key, V defaultValue)
Where,
     – key is the first parameter which is the key of the multi-value map.
     – defaultValue is the value which will be used as default in case the key is not present and a null is returned.

To understand the working of the Map.getOrDefault() method better letter look at the code snippet showing its usage-

Java 8 code to show usage of Map.getOrDefault() method

System.out.println("\nAvoiding a null return when fetching a non-existent key's entry using Map.getOrDefault() method\n");
List<Employee> empList2019 = employeeDOJMap.getOrDefault(2019, new ArrayList<>());
System.out.println("Size of empList 2019 = " + empList2019.size());



Java 8 – List.sort, List.replaceAll methods

New default method replaceAll() added to the List Interface in Java 8

Let us now take a look at the signature of the List.replaceAll() method –

default void replaceAll(UnaryOperator<E> operator)
Where,
     – operator is the only parameter and is an instance of a UnaryOperator Functional Interface.

What is a UnaryOperatorWhat is a UnaryOperator
java.util.function.UnaryOperator is a functional interface, and is a specialization of Function with the operand and the return value being of the same type. I.e. UnaryOperator<E> takes a single input of type E, and returns an output of the same type E.
Let us now see an example of using List.replaceAll() to do a specific action on all elements of a List. In the below code snippet, each of the 5 employees of some company are being given a salary hike of 10% across the board using List.replaceAll() method.

Java 8 code to do a specific change on all elements of a List using List.replaceAll()

package com.javabrahman.java8;
public class Employee {
  private String name;
  private Integer age;
  private Double salary;
  public Employee(String name, Integer age, Double salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
  }
  public String toString(){
    DecimalFormat dformat = new DecimalFormat(".##");
    return "Employee Name:"+this.name
        +"  Age:"+this.age
        +"  Salary:"+dformat.format(this.salary);
  }
//getters and setters for name, age and salary go here
//standard equals() and hashcode() code go here
}


//ListReplaceAllExample.java

package com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.Arrays;
import java.util.List;
public class ListReplaceAllExample {
  static List<Employee> employeeList = Arrays.asList(
      new Employee("Tom Jones", 45, 7000.00),
      new Employee("Harry Major", 25, 10000.00),
      new Employee("Ethan Hardy", 65, 8000.00),
      new Employee("Nancy Smith", 22, 12000.00),
      new Employee("Deborah Sprightly", 29, 9000.00));
  public static void main(String[] args) {
    employeeList.replaceAll(employee -> {
      employee.setSalary(employee.getSalary() * 1.1);
      return employee;
    });
    System.out.println("Employee list with all salaries incremented by 10%");
    employeeList.forEach(System.out::println);
  }
}


 OUTPUT of the above code

Employee list with all salaries incremented by 10%
Employee Name: Tom Jones   Age:45   Salary:7700.0
Employee Name: Harry Major   Age:25   Salary:11000.0
Employee Name: Ethan Hardy   Age:65   Salary:8800.0
Employee Name: Nancy Smith   Age:22   Salary:13200.0
Employee Name: Deborah Sprightly   Age:29   Salary:9900.0


New default method sort() added to the List Interface in Java 8

List.sort() is a new default method introduced in Java 8 which sorts the given list based on the Comparator instance passed to it as input. Let us start understanding the method by first looking at its signature –

default void sort(Comparator<? super E> c)
Where,

     – c is the only parameter and is an instance of a Comparator which is an ancestor of type E, where E is the type of the elements in the List being sorted.

Why create a new method List.sort() when Collections.sort() was already there

Prior to Java 8, Collections.sort() method was popularly used to lists. However, there was a drawback with Collections.sort() that it doesn’t sort in-place. An in-place sort saves both on memory (by not requiring space other than that occupied by its elements) and time ( as the twin tasks of creating a temporary copy of the list to be sorted and then copying the sorted elements back into the original list are no longer required).

List.sort(), however, does use an in-place variant of merge sort to sort the List elements. As a result it provides both the space and time benefits mentioned above. In fact, in Java 8, the Collections.sort() method itself internally calls List.sort() to sort the List elements.

Let us now take a look an example showing List.sort() usage. We will use the same list of employees as we used in the previous code snippet and sort them in the order of increasing order of their salary.
(Note – I am leaving out the code for Employee class below as it is the same as used in the replaceAll() code above.)

Java 8 code to sort a List using List.sort() default method

package com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.Arrays;
import java.util.List;
public class ListSortExample {
  static List<Employee> employeeList = Arrays.asList(
      new Employee("Tom Jones", 45, 7000.00),
      new Employee("Harry Major", 25, 10000.00),
      new Employee("Ethan Hardy", 65, 8000.00),
      new Employee("Nancy Smith", 22, 12000.00),
      new Employee("Deborah Sprightly", 29, 9000.00));
  public static void main(String[] args) {
    employeeList.sort((emp1, emp2)->
                      Double.compare(emp1.getSalary(),emp2.getSalary()));
    System.out.println("Employee list sorted by their salaries");
    employeeList.forEach(System.out::println);
  }
}

 OUTPUT of the above code

Employee list sorted by their salaries
Employee Name: Tom Jones   Age:45   Salary:7000.0
Employee Name: Ethan Hardy   Age:65   Salary:8000.0
Employee Name: Deborah Sprightly   Age:29   Salary:9000.0
Employee Name: Harry Major   Age:25   Salary:10000.0

Employee Name: Nancy Smith   Age:22   Salary:12000.0


Java 8 – Collection.removeIf method

Conditional removal from a Collection before Java 8

Java 7 code showing Collection handling using Iterator

//Employee.java(POJO class)
package com.javabrahman.java8;
public class Employee {
  private String name;
  private Integer age;
  private Double salary;
  public Employee(String name, Integer age, Double salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
  }
  public String toString(){
    return "Employee Name:"+this.name
        +"  Age:"+this.age
        +"  Salary:"+this.salary;
  }
//getters and setters for name, age and salary go here
//standard equals() and hashcode() code go here
}



//CollectionRemoveIfExample.java

com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CollectionRemoveIfExample {
  static List<Employee> employeeList = new ArrayList<>();
  public static void main(String[] args) {
    employeeList.add(new Employee("Tom Jones", 45, 7000.00));
    employeeList.add(new Employee("Harry Major", 25, 10000.00));
    employeeList.add(new Employee("Ethan Hardy", 65, 8000.00));
    employeeList.add(new Employee("Nancy Smith", 22, 12000.00));
    employeeList.add(new Employee("Deborah Sprightly", 29, 9000.00));
    for(Iterator empIterator=employeeList.iterator();
        empIterator.hasNext();) {
      Employee emp = empIterator.next();
      if(emp.getAge() > 30){
        empIterator.remove();
      }
    }
    System.out.println("Employees below the age of 30");
        employeeList.forEach(System.out::println);
  }
}

 OUTPUT of the above code

Employees below the age of 30
Employee Name: Harry Major   Age:25   Salary:10000.0
Employee Name: Nancy Smith   Age:22   Salary:12000.0
Employee Name: Deborah Sprightly   Age:29   Salary:9000.0

Conditional Removal from a Collection using Java 8’s Collection.removeIf() default method

Java 8’s java.util.Collection interface has a new default method added to it named removeIf(). This method is defined with the following signature –

default boolean removeIf(Predicate<? super E> filter)
Where,

     – filter is an instance of a Predicate Functional Interface.


Java 8 code showing Collection.removeIf() usage
public class CollectionRemoveIfExample {
  static List<Employee> employeeList = new ArrayList<>();
  public static void main(String[] args) {
    employeeList.add(new Employee("Tom Jones", 45, 7000.00));
    employeeList.add(new Employee("Harry Major", 25, 10000.00));
    employeeList.add(new Employee("Ethan Hardy", 65, 8000.00));
    employeeList.add(new Employee("Nancy Smith", 22, 12000.00));
    employeeList.add(new Employee("Deborah Sprightly", 29, 9000.00));
    employeeList.removeIf((Employee emp) -> emp.getAge() > = 30);
    System.out.println("Employees below the age of 30");
    employeeList.forEach(System.out::println);
  }
}
 OUTPUT of the above code
Employees below the age of 30
Employee Name: Harry Major   Age:25   Salary:10000.0
Employee Name: Nancy Smith   Age:22   Salary:12000.0
Employee Name: Deborah Sprightly   Age:29   Salary:9000.0


O(n2) Vs O(n) – Big performance improvement

Removal from an ArrayList using an iterator has time complexity of O(n2), while the same operation when performed using Java 8’s new Collection.removeIf() method has a complexity of O(n). This is a significant improvement in performance. If an application has large-sized ArrayLists then using the Collection.removeIf() method will result in the application being speeded up by an order of complexity, making the choice of the new method over the earlier one a no-brainer in such scenarios.




Java 8 – Iterable.forEach, Iterator.remove methods

New default method forEach() added to the Iterable Interface in Java 8

Iterable interface is a commonly extended interface among the Collections interfaces as it provides the ability to iterate over the members of a collection. Collection, List and Set are among the important Collections interfaces that extend Iterable, apart from other interfaces.

Collections classes extend Iterable
Java 8’s new Iterable.forEach() method has the following signature –

default void forEach(Consumer<? super T> action)
Where,
     – action is the only parameter and is an instance of a Consumer Functional Interface
     – forEach() is implemented in the Iterable interface itself as a default method.

Iterable.forEach() method ‘consumes’ all the elements of the iterable collection of elements passed to it. The logic for consumption is passed to the method as an instance of a Consumer functional interface. An important point to note is that the forEach method iterates internally over the collection of elements passed to it rather than externally. You can read about declarative internal iterators and how they differ from commonly used external iterators in this tutorial here.

Let us now take a look at Java code showing how to use Iterable.forEach() method for consuming the elements of an Iterable collection –

Java 8 code to iterate and consume using Iterable.forEach() method

package com.javabrahman.java8.collections;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class IterableForEachExample {
  public static void main(String args[]){
    List<Integer> intList= Arrays.asList(12,25,9);
    System.out.println("List elements printed using Iterable.forEach");
    intList.forEach(System.out::println);
   
    Set<Integer> intSet=new HashSet<>();
    intSet.add(50);
    intSet.add(1);
    System.out.println("Set elements printed using Iterable.forEach");
    intSet.forEach(System.out::println);
  }
}

 OUTPUT of the above code

List elements printed using Iterable.forEach
12
25
9
Set elements printed using Iterable.forEach
1
50
Explanation of the code


A List of primitive ints, named intList, is created using the Arrays.asList() method.
forEach() method is invoked on the List instance – intList. As we read above, List inherits the forEach() method’s default implementation from Iterable interface.
We pass a method reference to System.out.println() method, which is a Consumer type of function, as parameter to the forEach() method.

forEach() method internally iterates and consumes, or prints, the elements of intList.
Next we created an instance of a Set, named intSet, by using its concrete implementation HashSet.
Set also inherits Iterable. Hence, we are able to print the elements in intSet using the forEach() method similar to the way we did with intList.


New default method remove() added to Iterator interface in Java 8


Prior to Java 8, implementing Iterator interface without the support for remove() method implied that the designers had to override the method and throw an UnsupportedOperationException. Such an override was commonly done and over the years had become kind of staple in Iterator implementations not supporting the remove operation.

With Java 8 arrived the feature of adding default implementations of methods in interfaces itself. Java designers have used this new feature and added a default implementation of the remove() method in the Iterator interface itself which throws UnsupportedOperationException.

As a result, the practice of overriding the remove() method, whenever it wasn’t supported, has now been inverted to overriding the remove() method only when remove functionality has to be implemented. This has removed the unnecessary overhead of overriding and throwing the UnsuportedOperationException everytime when implementing an Iterator without remove functionality.

The default implementation of remove() method in Java 8’s Iterable is as shown below –

default void remove() {
  throw new UnsupportedOperationException("remove");
}

As you can see in the above code, the default implementation of Iterator.remove() method just throws an UnsupportedOperationException with message "remove".

Overview of Java 8’s new Date-Time API

Motivation for the major Date and Time API upgrade in Java 8

Date and Time is one area where until Java 7 programmers had to do make do with a poorly designed API. Not only were the commonly used java.util.Date(from JDK 1) and java.util.Calendar(from JDK 1.1) classes mutable, they were non-thread safe as well.

Several design decisions around these classes were not up to the otherwise high JDK design standards. For example – Date’s year offset started from the year 1900, the value contained in the Date object was not really a ‘date’ but was an offset from the Java epoch in milliseconds, the month index of Calendar starts from 0 (instead of 1), and so on…

The primary class provided for date formatting, java.text.DateFormat, was not thread safe. As a result, two concurrent threads utilizing the same DateFormat instance could lead to corrupted results!

Over the years, the lack of a good quality Date and Time library in core JDK led to the popularity of non-JDK date-time libraries such as Joda-Time1.

Core Ideas behind the design of new Date-Time API in Java 8

Thread Safety: java.util.Date and java.util.DateTimeFormatter were not thread safe. In today’s parallel programming paradigms, these are performance disasters waiting to happen. Java 8’s Date-time classes have been defined as immutable by default. So, if you modify the date or time using any of the in-built library methods then what you get back is a new instance with new values, the old instance remains the same. Result – A siginificant boost for concurrent processing environments.
Domain-driven design: Domain-driven design refers to deriving the class design and interaction based on their actual usage in business systems. So, classes and their interactions and straightforward. For example: There is no need to create a date out of milliseconds from Java epoch if you do not really require that. Just use an instance of java.time.LocalDate instead.
In-built support for multiple calendar systems: Java 8 has significantly improved the handling of non-ISO 8601 calendar systems such as Japanese or Thai calenders. This should further improve the acceptability of the new date-time API for implementing non-standard chronology specific requirements.

Java 8 Method References

 A method reference is a simplified form (or short-hand) of a lambda expression. It specifies the class name or the instance name followed by the method name. Instead of writing the lambda expression with all the details such as parameter and return type, a method reference lets you create a lambda expression from an existing method implementation.

Types of Method References

Type 1: Reference to a static method – If we intend to use a static method of a class then instead of writing the lengthier lambda expresion we can just refer to the method via method references.

Example 1: Reference to a static method
package com.javabrahman.java8;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
public class MethodReferenceExample {
 public static void main(String args[]){
  Function<String, Double> doubleConvertor=Double::parseDouble;
  Function<String, Double> doubleConvertorLambda=(String s) -> Double.parseDouble(s);
  System.out.println("double value using method reference - "+ doubleConvertor.apply("0.254"));
  System.out.println("double value using Lambda - "+ doubleConvertorLambda.apply("0.254"));  }
 }
}

Type 2: Reference to an instance method of a particular object –

Example 2:Reference to an instance method of an object
Consumer<String> stringPrinter=System.out::println;
Consumer<String> stringPrinterLambda=(String s) -> System.out.println(s);
stringPrinter.accept("Print from method reference based instance");
stringPrinterLambda.accept("Print from instance created from Lambda");


Type 3: Reference to an instance method of an arbitrary object of a particular type– Here the method reference used is of an instance method of an existing object.

Example 3:Reference to an instance method of an arbitrary object of a particular type
List<Integer> intList=Arrays.asList(1,2,3,4);
BiPredicate<List>Integer>,Integer> isPartOf=List::contains;
BiPredicate<List<Integer>,Integer> isPartOfLambda=(List<Integer> listInt, Integer value) -> listInt.contains(value);
System.out.println("Is 1 a part of the intList - "+ isPartOf.test(intList, 1));
System.out.println("Is 1 a part of the intList - "+ isPartOfLambda.test(intList, 1));

Type 4:  Constructor Reference

Example usage of Constructor References in code

STEP 1 – Let us define an Employee class with a constructor having 2 parameters as shown below –
Employee.java
public class Employee{
 String name;
 Integer age;
 //Contructor of employee
 public Employee(String name, Integer age){
  this.name=name;
  this.age=age;
 }
}

STEP 2 – Now lets create a factory interface for employees called EmployeeFactory. getEmployee() method of EmployeeFactory will return an employee instance as per the normal design of factory pattern

Interface EmployeeFactory.java
public Interface EmployeeFactory{
 public abstract Employee getEmployee(String name, Integer age);
}
Note – Since EmployeeFactory interface has a single abstract method hence it is a Functional Interface.

STEP 3 – The client side code to invoke EmployeeFactory to create Employee instances would be as follows –
Client-side code for invoking Factory interface
EmployeeFactory empFactory=Employee::new;
Employee emp= empFactory.getEmployee("John Hammond", 25);

Explanation of the code

The Constructor Reference of Employee is assigned to an instance of EmployeeFactory called empFactory. This is possible because the function descriptor of Employee constructor is same as that of the abstract method of the Functional Interface EmployeeFactory i.e.
(String, Integer) ->Employee.
Then the getEmployee method of empFactory is called with John’s name and age which internally calls the constructor of Employee and a new Employee instance emp is created.

Sunday, September 29, 2019

Constructor References Java 8

What are Constructor References: Constructor Introduced in Java 8, constructor references are specialized form of method references which refer to the constructors of a class. Constructor References can be created using the Class Name and the keyword new with the following syntax –
Syntax of Constructor References: <ClassName>::new

Constructor Reference Example: If you want reference to the constructor of wrapper class Integer, then you can write something like this –
Supplier<Integer> integerSupplier = Integer::new

Example usage of Constructor References in code

STEP 1 – Let us define an Employee class with a constructor having 2 parameters as shown below –

Employee.java
public class Employee{
 String name;
 Integer age;
 //Contructor of employee
 public Employee(String name, Integer age){
  this.name=name;
  this.age=age;
 }
}

STEP 2 – Now lets create a factory interface for employees called EmployeeFactory. getEmployee() method of EmployeeFactory will return an employee instance as per the normal design of factory pattern.


Interface EmployeeFactory.java

public Interface EmployeeFactory{
 public abstract Employee getEmployee(String name, Integer age);
}

Note – Since EmployeeFactory interface has a single abstract method hence it is a Functional Interface.


STEP 3 – The client side code to invoke EmployeeFactory to create Employee instances would be as follows –

Client-side code for invoking Factory interface

EmployeeFactory empFactory=Employee::new;
Employee emp= empFactory.getEmployee("John Hammond", 25);

Explanation of the code

The Constructor Reference of Employee is assigned to an instance of EmployeeFactory called empFactory. This is possible because the function descriptor of Employee constructor is same as that of the abstract method of the Functional Interface EmployeeFactory i.e.
(String, Integer) ->Employee.

Then the getEmployee method of empFactory is called with John’s name and age which internally calls the constructor of Employee and a new Employee instance emp is created.

Saturday, September 28, 2019

Programming Paradigms - Java 8 Enhancement

A programming paradigm is a way of thinking and seeing the world when it comes to programming. It borrows the Thomas Kuhn definition of paradigm and just applies it to the practice of programming.

The four main programming paradigms (according to Wikipedia) are: imperative, functional, object-oriented, and logic. Although object-oriented is pretty self explanatory, I won’t go into it nor will I discuss logic programming.


Object-oriented languages are good when you have a fixed set of operations on things and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods and the existing classes are left alone.

Functional languages are good when you have a fixed set of things and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types and the existing functions are left alone.

Method Overriding Interview Questions

Can we Override static methods in java?
We can declare static methods with same signature in subclass, but it is not considered overriding as there won’t be any run-time polymorphism. Hence the answer is ‘No’.
If a derived class defines a static method with same signature as a static method in base class, the method in the derived class hides the method in the base class.

An instance method cannot override a static method, and a static method cannot hide an instance method. For example, the following program has two compiler errors.

/* Java program to show that if static methods are redefined by
   a derived class, then it is not overriding but hidding. */

// Superclass
class Base {
   
    // Static method in base class which will be hidden in subclass
    public static void display() {
        System.out.println("Static or class method from Base");
    }
   
     // Non-static method which will be overridden in derived class
     public void print()  {
         System.out.println("Non-static or Instance method from Base");
    }
}

// Subclass
class Derived extends Base {
   
    // Static is removed here (Causes Compiler Error)
    public void display() {
        System.out.println("Non-static method from Derived");
    }
   
    // Static is added here (Causes Compiler Error)
    public static void print() {
        System.out.println("Static method from Derived");
   }
}


1) For class (or static) methods, the method according to the type of reference is called, not according to the object being referred, which means method call is decided at compile time.

2) For instance (or non-static) methods, the method is called according to the type of object being referred, not according to the type of reference, which means method calls is decided at run time.


Overriding method resolution will take care by JVM based on runtime Object. Hence overriding is
considered as runtime polymorphism or dynamic polymorphism or latebinding.
The process of overriding method resolution is also known as “dynamic method dispatch”.

native methods can be overridden as non-native, similarly we can override abstract methods,
synchronized methods.
We can override a non-abstract method as abstract also



Overriding in static methods

A static method can’t be overridden as non-static

Similarly a non-static method can’t be overridden as static method



If both parent and child class methods are static then there is no compile time error or run time error
it seems that overriding is happened but it is not overriding this concept is called “method hiding”.
All the rules of method hiding are exactly similar to overriding, except both methods declared as
static.
In the case of method hiding method resolution will take care by compiler based on reference
type(But not runtime object).


public static Object m1() throws Exception {
System.out.println("PArent");
return -1;
}

}

class C extends P {

public static Object m1() throws Exception {
System.out.println("Child");
return null;
}
}

public class test {
public static void main(String args[]) throws Exception {
P p = new C();
p.m1();
}
}

O/P:
Parent

In the case of method hiding the method resolution will take care by compiler based on reference
type. Hence method hiding is considered as ‘static polymorphism’ or ‘compile time polymorphism’ or
‘early binding’.

Rules :

1. Visibility or access Modified can only increase i e  if parent is public child can only be public.
2. Return Types in Child class should be co-variant types ie if parent is Object then child can be String or integer etc but the vice versa is not true.
3. while overriding the size of checked exceptions we are not allowed to increase in throws class but
we can decrease the size of checked exceptions. But there are no restrictions on unchecked
exceptions.


Overriding in the case of Variable

Overriding concept is not applicable for variables. And it is applicable only for methods.
Variable resolution always takes care by compiler based on reference type.
Ex:
class P
{
int i = 888;
static
non-static
}
class C extends P
{
int i = 999;
}
class Test
{
public static void main(String arg[])
{
P p = new P();
Case1: System.out.println(p.i); //888
C c = new C();
Case2: System.out.println(c.i); //999
P p1 = new C();
Case3: System.out.println(p1.i); //888
}
}



1. Conclusion for Handling such Exceptions: Hence, following conclusions can be derived from the above examples:

If SuperClass does not declare an exception, then the SubClass can only declare unchecked exceptions, but not the checked exceptions.
If SuperClass declares an exception, then the SubClass can only declare the child exceptions of the exception declared by the SuperClass, but not any other exception.
If SuperClass declares an exception, then the SubClass can declare without exception.





Consider the following parent class method declaration….!
Parent : public void m1(int i)
Which of the following methods are allowed in the child class.
Child : 1) private void m1(float f)throws Exception (overloading)
2) public void m1(int i)throws classCastException (overloading)
3) public final void m1(int i) (overloading)
4) private abstract void m1(long l)throws Exception X (private & abstract)
5) public synchronized int m1() throws IOException (over loading)
6) public int m1(int i) X
7) public void m1(int i)throws Exception X (Exception Increased)

Autoboxing and Unboxing in Java

The automatic conversion of primitive data types into its equivalent Wrapper type is known as boxing and opposite operation is known as unboxing.

Autoboxing and Unboxing with method overloading

In method overloading, boxing and unboxing can be performed. There are some rules for method overloading with boxing:

Widening beats boxing
Widening beats varargs
Boxing beats varargs


Widening beats boxing

class Boxing1{ 
  static void m(int i){System.out.println("int");} 
  static void m(Integer i){System.out.println("Integer");} 
 
  public static void main(String args[]){ 
   short s=30; 
   m(s); 
 } 

     
Output:int


Widening beats varargs

class Boxing2{ 
  static void m(int i, int i2){System.out.println("int int");} 
  static void m(Integer... i){System.out.println("Integer...");} 
 
  public static void main(String args[]){ 
   short s1=30,s2=40; 
   m(s1,s2); 
 } 

     

Output:int int


Boxing beats varargs
   
class Boxing3{ 
  static void m(Integer i){System.out.println("Integer");} 
  static void m(Integer... i){System.out.println("Integer...");} 
 
  public static void main(String args[]){ 
   int a=30; 
   m(a); 
 } 

     
Output:Integer


Method overloading with Widening and Boxing

class Boxing4{ 
  static void m(Long l){System.out.println("Long");} 
 
  public static void main(String args[]){ 
   int a=30; 
   m(a); 
 } 

     
Output:Compile Time Error

Compiler uses valueOf() method to convert primitive to Object and uses intValue(), doubleValue() etc to get primitive value from Object.

Read more: https://javarevisited.blogspot.com/2012/07/auto-boxing-and-unboxing-in-java-be.html#ixzz60pL8Qd1X

Unnecessary Object creation due to Autoboxing in Java

One of the dangers of autoboxing is throw away object which gets created if autoboxing occurs in a loop. Here is an example of how unnecessary object can slow down your application :

 Integer sum = 0;
 for(int i=1000; i<5000; i++){
   sum+=i;
 }

In this code sum+=i will expand as sum = sum + i and since + operator is not applicable to Integer object it will trigger unboxing of sum Integer object and then autoboxing of result which will be stored in sum which is Integer as shown below :

sum = sum.intValue() + i;
Integer sum = new Integer(result);     
   
here since the sum is Integer, it will create around 4000 unnecessary Integer object which are just throw away and if this happens on a large scale has It potential to slow down system with frequent GC for arithmetic calculation always prefer primitive over boxed primitive and look for unintentional autoboxing in Java

There is another problem as well when you compare int variable to Integer object using == operator, the Integer object is converted to a primitive value. This can throw null pointer exception if the Integer object is null, which can crash your program.



Comparing Integer object with == in Java

Why you should not compare Integer using == in Java 5Some of the JVM cache objects of some wrapper class e.g. Integer from -128 to 127 and return same object which if compare via “ ==” can return true but after this range this validity doesn't work and to make it worse this behavior is JVM dependent so better avoid this kind of check and use equals() method. e.g.

Integer i1 = 260;
Integer i2 = 260;

if (i1 == i2) {
    System.out.println("i1 and i2 is equal");
} else {
   System.out.println("i1 and i2 is not equal ");
}

Here you will most probably get "i1 and i2 is not equal " at least in my machine.
because in this case, unboxing operation is not involved. The literal 260 is boxed into two different Integer objects ( again it varies between JVM to JVM) , and then those objects are compared with ==. The result is false, as the two objects are different instances, with different memory addresses. Because both sides of the == expression contain objects, no unboxing occurs.

Integer i1 = 100;
Integer i2 = 100;

if (i1 == i2) {
    System.out.println("i1 and i2 is equal");
} else {
   System.out.println("i1 and i2 is not equal ");
}


Here, most probably you will get the text "i1 and i2 is equal".
Because int values from -127 to 127 are in a range which most JVM will like to cache so the VM actually uses the same object instance (and therefore memory address) for both i1 and i2. As a result, == returns a true result.

This is very indeterministic and only shown by example since some JVM do optimization at certain integer value and try to return same object every time but its not guaranteed or written behavior.

So best is to avoid this kind of code in post Java 1.5 and instead use equals() method to compare Integers in Java, which is more deterministic and correct.



Java Output Questions

1. public class Test {

public void foo(Object o) {
System.out.println("Object");
}

public void foo(String s) {
System.out.println("String");
}
public static void main(String[] args) {
new Test().foo(null);
}

}

bove program compiles perfectly and when we run it, it prints “String”.

So the method foo(String s) was called by the program. The reason behind this is java compiler tries to find out the method with most specific input parameters to invoke a method. We know that Object is the parent class of String, so the choice was easy. Here is the excerpt from Java Language Specification

If more than one member method is both accessible and applicable to a method invocation … The Java programming language uses the rule that the most specific method is chosen.

The reason I am passing “null” is because it works for any type of arguments, if we pass any other objects the choice of method for the java compiler is easy.






You will get compile time error as The method foo(Object) is ambiguous for the type Test because both String and Integer class have Object as parent class and there is no inheritance. So java compiler doesn’t consider any of them to be more specific, hence the method ambiguous call error.


public class Test {

public void foo(Object o) {
System.out.println("Object");
}

public void foo(Exception e) {
System.out.println("Exception");
}

public void foo(NullPointerException ne) {
System.out.println("NullPointerException");
}

public static void main(String[] args) {
new Test().foo(null);
}

}
As above explained, here foo(NullPointerException ne) is the most specific method because it’s inherited from Exception class and hence this code compiles fine and when executed prints “NullPointerException”.

How to Create Immutable Class in java?

An object is immutable if its state cannot change after construction. Immutable objects don’t expose any way for other objects to modify their state; the object’s fields are initialized only once inside the constructor and never change again.

Some Popular Immutable Classes
String is the most popular immutable class in Java. Once initialized its value cannot be modified. Operations like trim(), substring(), replace() always return a new instance and don’t affect the current instance, that’s why we usually call trim() as the following:

String alex = "Alex";
alex = alex.trim();

Another example from JDK is the wrapper classes like: Integer, Float, Boolean … these classes don’t modify their state, however they create a new instance each time you try to modify them.

Integer a =3;
a += 3;
After calling a += 3, a new instance is created holding the value: 6 and the first instance is lost.

In order to create an immutable class, you should follow the below steps:

Make your class final, so that no other classes can extend it.

Make all your fields final, so that they’re initialized only once inside the constructor and never modified afterward.

Don’t expose setter methods.

When exposing methods which modify the state of the class, you must always return a new instance of the class.

If the class holds a mutable object:
Inside the constructor, make sure to use a clone copy of the passed argument and never set your mutable field to the real instance passed through constructor, this is to prevent the clients who pass the object from modifying it afterwards.

Make sure to always return a clone copy of the field and never return the real object instance.

Simple Immutable Class

Let’s follow the above steps and create our own immutable class (ImmutableStudent.java).

package com.programmer.gate.beans;
public final class ImmutableStudent {
    private final int id;
    private final String name;
    public ImmutableStudent(int id, String name) {
        this.name = name;
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }

}

Passing Mutable Objects to Immutable Class
Now, let’s complicate our example a bit, we create a mutable class called Age and add it as a field to ImmutableStudent:

package com.programmer.gate.beans;
public class Age {
    private int day;
    private int month;
    private int year;
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
    this.day = day;
    }
    public int getMonth() {
    return month;
    }
    public void setMonth(int month) {
    this.month = month;
    }
    public int getYear() {
    return year;
    }
    public void setYear(int year) {
    this.year = year;
    }
}
package com.programmer.gate.beans;
public final class ImmutableStudent {
    private final int id;
    private final String name;
    private final Age age;
    public ImmutableStudent(int id, String name, Age age) {
    this.name = name;
    this.id = id;
    this.age = age;
    }
    public int getId() {
    return id;
    }
    public String getName() {
    return name;
    }
    public Age getAge() {
    return age;
    }
}
So, we added a new mutable field of type Age to our immutable class and assign it as normal inside the constructor.

Let’s create a simple test class and verify that ImmutableStudent is no more immutable:

public static void main(String[] args) {
    Age age = new Age();
    age.setDay(1);
    age.setMonth(1);
    age.setYear(1992);
    ImmutableStudent student = new ImmutableStudent(1, "Alex", age);
    System.out.println("Alex age year before modification = " + student.getAge().getYear());
    age.setYear(1993);
    System.out.println("Alex age year after modification = " + student.getAge().getYear());
}
After running the above test, we get the following output:

Alex age year before modification = 1992
Alex age year after modification = 1993
We claim that ImmutableStudent is an immutable class whose state is never modified after construction, however in the above example we are able to modify the age of Alex even after constructing Alex object. If we go back to the implementation of ImmutableStudent constructor, we find that age field is being assigned to the instance of the Age argument, so whenever the referenced Age is modified outside the class, the change is reflected directly on the state of Alex.

In order to fix this and make our class again immutable, we follow step #5 from the steps that we mention above for creating an immutable class. So we modify the constructor in order to clone the passed argument of Age and use a clone instance of it.

public ImmutableStudent(int id, String name, Age age) {
    this.name = name;
    this.id = id;
    Age cloneAge = new Age();
    cloneAge.setDay(age.getDay());
    cloneAge.setMonth(age.getMonth());
    cloneAge.setYear(age.getYear());
    this.age = cloneAge;
}
Now, if we run our test, we get the following output:

Alex age year before modification = 1992
Alex age year after modification = 1992
As you see now, the age of Alex is never affected after construction and our class is back to immutable.

3.3. Returning Mutable Objects From Immutable Class
However, our class still has a leak and is not fully immutable, let’s take the following test scenario:

public static void main(String[] args) {
    Age age = new Age();
    age.setDay(1);
    age.setMonth(1);
    age.setYear(1992);
    ImmutableStudent student = new ImmutableStudent(1, "Alex", age);
    System.out.println("Alex age year before modification = " + student.getAge().getYear());
    student.getAge().setYear(1993);
    System.out.println("Alex age year after modification = " + student.getAge().getYear());
}
Output:

Alex age year before modification = 1992
Alex age year after modification = 1993
Again according to step #4, when returning mutable fields from immutable object, you should return a clone instance of them and not the real instance of the field.

So we modify getAge() in order to return a clone of the object’s age:

public Age getAge() {
    Age cloneAge = new Age();
    cloneAge.setDay(this.age.getDay());
    cloneAge.setMonth(this.age.getMonth());
    cloneAge.setYear(this.age.getYear());
    return cloneAge;
}
Now the class becomes fully immutable and provides no way or method for other objects to modify its state.

Alex age year before modification = 1992
Alex age year after modification = 1992
4. Conclusion
Immutable classes provide a lot of advantages especially when used correctly in a multi-threaded environment. The only disadvantage is that they consume more memory than the traditional class since upon each modification of them a new object is created in the memory... but, a developer should not overestimate the memory consumption as its negligible compared to the advantages provided by these type of classes.

Finally, an object is immutable if it can present only one state to the other objects, no matter how and when they call its methods. If so it’s thread safe by any definition of thread-safe.



More Info on Immutable Class

ImmutableClass.java
import java.util.Date;

/**
* Always remember that your instance variables will be either mutable or immutable.
* Identify them and return new objects with copied content for all mutable objects.
* Immutable variables can be returned safely without extra effort.
* */
public final class ImmutableClass
{

    /**
    * Integer class is immutable as it does not provide any setter to change its content
    * */
    private final Integer immutableField1;

    /**
    * String class is immutable as it also does not provide setter to change its content
    * */
    private final String immutableField2;

    /**
    * Date class is mutable as it provide setters to change various date/time parts
    * */
    private final Date mutableField;

    //Default private constructor will ensure no unplanned construction of class
    private ImmutableClass(Integer fld1, String fld2, Date date)
    {
        this.immutableField1 = fld1;
        this.immutableField2 = fld2;
        this.mutableField = new Date(date.getTime());
    }

    //Factory method to store object creation logic in single place
    public static ImmutableClass createNewInstance(Integer fld1, String fld2, Date date)
    {
        return new ImmutableClass(fld1, fld2, date);
    }

    //Provide no setter methods

    /**
    * Integer class is immutable so we can return the instance variable as it is
    * */
    public Integer getImmutableField1() {
        return immutableField1;
    }

    /**
    * String class is also immutable so we can return the instance variable as it is
    * */
    public String getImmutableField2() {
        return immutableField2;
    }

    /**
    * Date class is mutable so we need a little care here.
    * We should not return the reference of original instance variable.
    * Instead a new Date object, with content copied to it, should be returned.
    * */
    public Date getMutableField() {
        return new Date(mutableField.getTime());
    }

    @Override
    public String toString() {
        return immutableField1 +" - "+ immutableField2 +" - "+ mutableField;
    }
}
Now its time to test our class:

TestMain.java
class TestMain
{
    public static void main(String[] args)
    {
        ImmutableClass im = ImmutableClass.createNewInstance(100,"test", new Date());
        System.out.println(im);
        tryModification(im.getImmutableField1(),im.getImmutableField2(),im.getMutableField());
        System.out.println(im);
    }

    private static void tryModification(Integer immutableField1, String immutableField2, Date mutableField)
    {
        immutableField1 = 10000;
        immutableField2 = "test changed";
        mutableField.setDate(10);
    }
}
Program output:

Console
100 - test - Tue Oct 30 21:34:08 IST 2012
100 - test - Tue Oct 30 21:34:08 IST 2012
As it can be seen that even changing the instance variables using their references does not change their value, so the class is immutable.

Immutable classes in JDK
Apart from your written classes, JDK itself has lots of immutable classes. Given is such a list of immutable classes in Java.

String
Wrapper classes such as Integer, Long, Double etc.
Immutable collection classes such as Collections.singletonMap() etc.
java.lang.StackTraceElement
Java enums (ideally they should be)
java.util.Locale
java.util.UUID

3. Benefits of making a class immutable
Lets first identify advantages of immutable class. In Java, immutable classes are:

are simple to construct, test, and use
are automatically thread-safe and have no synchronization issues
do not need a copy constructor
do not need an implementation of clone
allow hashCode() to use lazy initialization, and to cache its return value
do not need to be copied defensively when used as a field
make good Map keys and Set elements (these objects must not change state while in the collection)
have their class invariant established once upon construction, and it never needs to be checked again
always have “failure atomicity” (a term used by Joshua Bloch) : if an immutable object throws an exception, it’s never left in an undesirable or indeterminate state

Performance Improvement for HashMap in Java 8

HashMap in Java
The HashMap class extends AbstractMap and implements Map interface. HashMap is a key and value collection in java. The HashMap stores the data in key and value format. It provides the basic implementation of the Map interface of Java. We can put a value with using a key and also we can access this value using that key. It uses a hash table to store the map. This allows the execution time of the get() and the put() methods to remain the same.

The traversal of HashMap, get(), and other methods lookup time of HashMap have a negative impact due to hash collisions. This situation you can face when multiple keys end up in the same bucket, then values along with their keys are placed in a linked list. So, the retrieval time of elements from HashMap increases from O(1) to O(n). Because the linked list has to be traversed to get the entry in the worst case scenario.

But Java 8 has come with the following new strategy for HashMap objects in case of high collisions.

To address this issue, Java 8 hash elements use balanced trees instead of linked lists after a certain threshold is reached. Which means HashMap starts with storing Entry objects in a linked list but after the number of items in a hash becomes larger than a certain threshold. The hash will change from using a linked list to a balanced tree.
Above changes ensure the performance of O(log(n)) in worst case scenarios and O(1) with proper hashCode().
The alternative String hash function added in Java 7 has been removed.


Another Blog also stated :

Basically when a bucket becomes too big (currently: TREEIFY_THRESHOLD = 8), HashMap dynamically replaces it with an ad-hoc implementation of tree map.



The fix has been implemented in the classes java.util.HashMap, java.util.LinkedHashMap and java.util.concurrent.ConcurrentHashMap. No interfaces or methods specifications have been changed, only the behavior in the implementation of the concurrent hash map is different. So there is no need to change the applications using these classes. However, the iteration order when accessing hash maps entries may be different, this is explained in this article and should be reviewed in your programs.


 O(log n) performance
In this case, it means that the algorithm will perform better when the amount of data is larger. Performance is not directly proportional to the large of the processed data but in a log n relation. O(log n) performs better than O(n).

 Balanced trees
A tree is balanced if the left and the right sub trees are balanced (recursion!) and their height differ by at most one. The main goal is to keep the depths of all nodes to be O(log n). The maintenance of the balanced tree has a penalty in the insertion of new elements but improve the indexing and accessing performance.

Thursday, September 26, 2019

Where does class, object, reference variable get stored in java.

Following are points you need to consider about memory allocation in java.

Note: Object and Object references are different things.

1)There is new keyword in java used very often to create new object. But what new does is allocate memory for the object of class you are making and returns a reference.

That means whenever you create an object as static or local, it gets stored in HEAP.

2) All the class variable primitive or object references (which is just a pointer to location where object is stored i.e. heap) are also stored in heap.

3) Classes loaded by classloader and static variables and static object references are stored in a special location in heap which permanent generation.

4) Local primitive variables, local object references and method parameters are stored in Stack.

5) Local Functions (methods) are stored in stack but Static functions(methods) goes in permanent storage.

6) All the information related to a class like name of the class, Object arrays asscociated with the class, internal objects used by JVM (like java/lang/Object) and optimization information goes into the Permanent Generation area.

7) To understand stack, heap, data you should read about Processes and Process Control Block in Operating Systems.

Java Encapsulation | Does Static break Encapsulation

What is encapsulation and why is it used.?

Encapsulation is one of the four fundamental OOP concepts.Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other code defined outside the class. Access to the data and code is tightly controlled by an interface.

The main benefit of encapsulation is the ability to modify our implemented code without breaking the code of others who use our code. With this feature Encapsulation gives maintainability, flexibility and extensibility to our code.

Take a small example:

public class EncapTest{

   private String name;
   private String idNum;
   private int age;

   public int getAge(){
      return age;
   }

   public String getName(){
      return name;
   }

   public String getIdNum(){
      return idNum;
   }

   public void setAge( int newAge){
      age = newAge;
   }

   public void setName(String newName){
      name = newName;
   }

   public void setIdNum( String newId){
      idNum = newId;
   }
}
The above methods are called Accessors(aka getters and setters). Now you might ask,

Why should you use accessors..? There are actually many good reasons to consider using accessors rather than directly exposing fields of a class.Getter and Setters make APIs more stable.
For instance, consider a field public in a class which is accessed by other classes. Now later on, you want to add any extra logic while getting and setting the variable. This will impact the existing client that uses the API. So any changes to this public field will require change to each class that refers it. On the contrary, with accessor methods, one can easily add some logic like cache some data, lazily initialize it later. Moreover, one can fire a property changed event if the new value is different from the previous value. All this will be seamless to the class that gets value using accessor method.

static breaks encapsulation rule because it is possible to access it without settters or getters but directly. If you declare a variable like this : public static or static, when calling it from another class you can write : object.variable = value;.

The technical implementation of them is to allow state to be maintained across all instances of a class. The problem is that this is intrinsically not OOP because it disregards encapsulation. If a variable can be altered by any instance of a class then the fundamental principle behind encapsulation/information hiding is lost entirely: An object is no longer in complete control of its state. Its state now relies on variables which are essentially global. Which we know is bad. Even private static variables maintain state at a global level but simply limit its access. Any instance of the object can alter the static variable which causes ambiguity as individual instances of the object no longer have control over their own state. State changes can arbitrarily happen without knowledge of an object which relies on that state which is problematic because the object may not work correctly when this happens. Much as it's often said that "Inheritance breaks encapsulation" statics do this in a far more severe way: By not just exposing internal implementation but also by exposing internal state.

String in JAVA

1. Strings are immutable and final in Java.
2. Strings are maintained in String Pool.
3. Difference between String literal and New String object in Java
String s = "a";
String q = "a";
String w = new String("a");
String w1 = new String("a");

System.out.println(s == q);
System.out.println(s == w);
System.out.println(w1 == w);

Output :
true
false
false

Both expression gives you String object, but there is subtle difference between them. When you create String object using new() operator, it always create a new object in heap memory. On the other hand, if you create object using String literal syntax e.g. "a", it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists. Otherwise it will create a new string object and put in string pool for future re-use.

w/w1 is then lost (eligible for GC) if later unused. String literals on the other hand are reused.

These double quoted literal is known as String literal and the cache which stored these String instances are known as as String pool. In earlier version of Java, I think up-to Java 1.6 String pool is located in permgen area of heap, but in Java 1.7 updates its moved to main heap area. Earlier since it was in PermGen space, it was always a risk to create too many String object, because its a very limited space, default size 64 MB and used to store class metadata e.g. .class files. Creating too many String literals can cause java.lang.OutOfMemory: permgen space. Now because String pool is moved to a much larger memory space, it's much more safe. By the way, don't misuse memory here, always try to minimize temporary String object e.g. "a", "b" and then "ab". Always use StringBuilder to deal with temporary String object.

Java by default doesn't put all String object into String pool, instead they gives you flexibility to explicitly store any arbitrary object in String pool. You can put any object to String pool by calling intern() method of java.lang.String class. Though, when you create using String literal notation of Java, it automatically call intern() method to put that object into String pool, provided it was not present in the pool already. This is another difference between string literal and new string, because in case of new, interning doesn't happen automatically, until you call intern() method on that object. Also don't forget to use StringBuffer and StringBuilder for string concatenation, they will reduce number

4. "+" is overloaded for String concatenation
Java doesn't support Operator overloading but String is special and + operator can be used to concatenate two Strings. It can even used to convert int, char, long or double to convert into String by simply concatenating with empty string "". internally + is implemented using StringBuffer prior to Java 5 and StringBuilder from Java 5 onwards. This also brings point of using StringBuffer or StringBuilder for manipulating String. Since both represent mutable object they can be used to reduce string garbage created because of temporary String.


5. Why char array is better than String for storing password?

1) Since Strings are immutable in Java if you store password as plain text it will be available in memory until Garbage collector clears it and since String are used in String pool for reusability there is pretty high chance that it will be remain in memory for long duration, which pose a security threat. Since any one who has access to memory dump can find the password in clear text and that's another reason you should always used an encrypted password than plain text. Since Strings are immutable there is no way contents of Strings can be changed because any change will produce new String, while if you char[] you can still set all his element as blank or zero. So Storing password in character array clearly mitigates security risk of stealing password.

2) Java itself recommends using getPassword() method of JPasswordField which returns a char[] and deprecated getText() method which returns password in clear text stating security reason. Its good to follow advice from Java team and adhering to standard rather than going against it.

3) With String there is always a risk of printing plain text in log file or console but if use Array you won't print contents of array instead its memory location get printed. though not a real reason but still make sense.

String strPassword="Unknown";
char[] charPassword= new char[]{'U','n','k','w','o','n'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);

String password: Unknown
Character password: [C@110b053


That's all on why character array is better choice than String for storing passwords in Java.  Though using char[] is not just enough you need to erase content to be more secure. I also suggest working with hash'd or encrypted password instead of plain text and clearing it from memory as soon as authentication is completed.

6. What is String pool in Java?

Another tough Java question asked in String interview. String pool is a special storage area in Java heap, mostly located on PerGen space, to store String literals like "ABC". When Java program creates a new String using String literal, JVM checks for that String in the pool and if String literal is already present in the pool than the same object is returned instead of creating a whole new object. String pool check is only performed when you create String as literal, if you create String using new() operator, a new String object will be created even if String with the same content is available in the pool.

7. What does intern() method do in Java?
As discussed in previous String interview question, String object created by new() operator is by default not added in String pool as opposed to String literal. The intern method allows putting a String object into a pool.

8. Why String is Immutable or Final in Java

The string is Immutable in Java because String objects are cached in String pool. Since cached String literals are shared between multiple clients there is always a risk, where one client's action would affect all another client. For example, if one client changes the value of String "Test" to "TEST", all other clients will also see that value as explained in the first example. Since caching of String objects was important from performance reason this risk was avoided by making String class Immutable. At the same time, String was made final so that no one can compromise invariant of String class e.g. Immutability, Caching, hashcode calculation etc by extending and overriding behaviors. Another reason of why String class is immutable could die due to HashMap.

Since Strings are very popular as HashMap key, it's important for them to be immutable so that they can retrieve the value object which was stored in HashMap. Since HashMap works in the principle of hashing, which requires same has value to function properly. Mutable String would produce two different hashcodes at the time of insertion and retrieval if contents of String was modified after insertion, potentially losing the value object in the map.

9. Why String is Final in Java

1) Imagine String pool facility without making string immutable , its not possible at all because in case of string pool one string object/literal e.g. "Test" has referenced by many reference variables, so if any one of them change the value others will be automatically gets affected

2) String has been widely used as parameter for many Java classes

In case, if String is not immutable, this would lead serious security threat, I mean someone can access to any file for which he has authorization, and then can change the file name either deliberately or accidentally and gain access to that file. Because of immutability, you don't need to worry about that kind of threats. This reason also gels with, Why String is final in Java, by making java.lang.String final, Java designer ensured that no one overrides any behavior of String class.

3)Since String is immutable it can safely share between many threads which is very important for multithreaded programming and to avoid any synchronization issues in Java,

4) Another reason of Why String is immutable in Java is to allow String to cache its hashcode, being immutable String in Java caches its hashcode, and do not calculate every time we call hashcode method of String, which makes it very fast as hashmap key to be used in hashmap in Java.

5) Another good reason of Why String is immutable in Java suggested by Dan Bergh Johnsson on comments is: The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects. Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"

Read more: https://javarevisited.blogspot.com/2010/10/why-string-is-immutable-or-final-in-java.html#ixzz60e9duxmt

java.lang.OutOfMemoryError: PermGen space Cause and Solution

PermGen Space of the heap is used to store classes and Metadata about classes in Java. When a class is loaded by a classloader it got stored in PermGen space, it gets unloaded only when the classloader which loaded this class got garbage collected. If any object retains reference of classloader than it's not garbage collected and Perm Gen Space is not freed up.

This causes a memory leak in PermGen Space and eventually cause java.lang.OutOfMemoryError: PermGen space. Another important point is that when you deploy your web application a new Classloader gets created and it loads the classes used by the web application. So if Classloader doesn't get garbage collected when your web application stops you will have a memory leak in tomcat.

Saying that a Java program can have memory leak is little surprising for many programers, because they think that Garbage Collector will reclaim memory, and that's one of the reason, why Java is popular programming language. Bug, GC has it's limitation, it can not reclaim the object, which is undesired but still refrenced by some object in Program. This memory, which should be free but still can not be reclaimed is called Memory leak in Java. If you see java.lang.OutOfMemoryError: Java heap space, even after increasing heap space, than it's good to analyze memory pattern for any possible memory leak. There are tools like Profiler (JProbe, Yourkit or Netbeans Profiler), JConsole, VisualVM, which you can use to see memory usage of Java application to confirm memory leak. There are even tools like Plumbr, which can help you to find memory leaks in Java. Though this would be as easy as increasing heap memory to fix java.lang.OutOfMemoryError: Java heap space.

Sunday, September 22, 2019

Spring Boot Interview Questions - Part 1

1. What does the @SpringBootApplication annotation do internally?

@SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan with their default attributes.

@Configuration :
Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example:
 @Configuration
 public class AppConfig {

     @Bean
     public MyBean myBean() {
         // instantiate, configure and return bean ...
     }
 }

@EnableAutoConfiguration
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, if HSQLDB is on your classpath, and you have not manually configured any database connection beans, then Spring Boot auto-configures an in-memory database.

@ComponentScan
Configures component scanning directives for use with @Configuration classes. Provides support parallel with Spring XML's <context:component-scan> element.
Either basePackageClasses() or basePackages() (or its alias value()) may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.

2. How to disable a specific auto-configuration class or exclude any package?


//By using "exclude"- in classpath
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})


//By using "excludeName" - not in classpath
@EnableAutoConfiguration(excludeName={Foo.class})

//By using property file
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

3.  What is Spring Actuator? What are its advantages?

It provides many features, i.e. what beans are created, the mapping in the controller, the CPU usage, etc. Automatically gathering and auditing health and metrics can then be applied to your application.

It provides a very easy way to access the few production-ready REST endpoints and fetch all kinds of information from the web. But by using these endpoints, you can do many things to see here the endpoint docs.

Enabling/disabling the actuator is easy; the simplest way is to enable features to add the dependency (Maven/Gradle) to the spring-boot-starter-actuator, i.e. Starter. If you don't want the actuator to be enabled, then don't add the dependency.

4. What is a shutdown in the actuator?

Shutdown is an endpoint that allows the application to be gracefully shutdown. This feature is not enabled by default. You can enable this by using management.endpoint.shutdown.enabled=true in your application.properties file. But be careful about this if you are using this.

5. Is this possible to change the port of Embedded Tomcat server in Spring boot?

Yes, it's possible to change the port. You can use the application.properties file to change the port. But you need to mention "server.port" (i.e. server.port=8081). Make sure you have application.properties in your project classpath; REST Spring framework will take care of the rest. If you mention server.port=0 , then it will automatically assign any available port.

6. Can we override or replace the Embedded Tomcat server in Spring Boot?

Yes, we can replace the Embedded Tomcat with any other servers by using the Starter dependencies. You can use spring-boot-starter-jetty  or spring-boot-starter-undertow as a dependency for each project as you need.

spring-boot-starter-web comes with Embedded Tomcat. We need to exclude this dependency.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Adding Dependencies
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

7.Can we disable the default web server in the Spring Boot application?

The major strong point in Spring is to provide flexibility to build your application loosely coupled. Spring provides features to disable the web server in a quick configuration. Yes, we can use the application.properties to configure the web application type, i.e.  spring.main.web-application-type=none.


8. How does it work? How does it know what to configure?

• Auto-configuration works by analyzing the classpath

The meat of the code is the use of the @ConditionalOnClass annotation

9. How to reload my changes on Spring Boot without having to restart server?

Include following maven dependency in the application.
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>springloaded</artifactId>
 <version>1.2.6.RELEASE</version>
</dependency>

Automatic restart

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>


10. How to implement Spring web using Spring boot?
Web Application Convenience
• Boot automatically configures
– A DispatcherServlet & ContextLoaderListener
– Spring MVC using same defaults as @EnableWebMvc
• Plus many useful extra features:
– Static resources served from classpath
• /static, /public, /resources or /META-INF/resources
– Templates served from /templates
• If Velocity, Freemarker, Thymeleaf, or Groovy on classpath
– Provides default /error mapping
• Easily overridden
– Default MessageSource for I18N

11. How to configure datasource using Spring boot?
• Use either spring-boot-starter-jdbc or spring-boot-starterdata-jpa and include a JDBC driver on classpath
• Declare properties

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
– Spring Boot will create a DataSource with properties set
– Will even use a connection pool if the library is found on the classpath!


12 How do you add Add a Servlet, Filter or Listener to an application?
There are two ways to add Servlet, Filter, ServletContextListener and the other listeners supported by the Servlet spec to your application. You can either provide Spring beans for them or enable scanning for Servlet components.

13. How do you Enable HTTP response compression in spring boot?
HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled by adding server.compression.enabled=true in application.properties.

14. How to execute Spring Batch jobs on startup?
Spring Batch auto-configuration is enabled by adding @EnableBatchProcessing (from Spring Batch) somewhere in your context. By default, it executes all Jobs in the application context on startup.

15. How do you Create a deployable war file in spring boot?
Step 1: Extend SpringBootServletInitializer and override its configure method.
Step 2: Change packing type to war in pom.xml or in build.gradle.
Step 3: Mark the embedded servlet container dependency as provided.

16.  How to write custom log configuration in spring boot?
You can force Spring Boot to use a particular logging system using the org.springframework.boot.logging.LoggingSystem system property. The value should be the fully-qualified class name of a logging system implementation. You can also disable Spring Boot’s logging configuration entirely by using a value of none.

17. What are Profiles in spring boot?
Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments. Any @Component or @Configuration can be marked with @Profile to limit when it is loaded.

18. What is spring-boot-starter-parent?
The spring-boot-starter-parent is a special starter that makes Maven or Gradle dependency-management easier by adding jars to your classpath.
It adds a basic set of spring jars needed for any type of spring based applications.

19. Can you control logging with Spring Boot? How?
Yes, we can control logging with Spring Boot by specifying log levels on application.properties file. Spring Boot loads this file when it exists in the classpath and it can be used to configure both Spring Boot and application code.

Spring Boot uses Commons Logging for all internal logging and you can change log levels by adding following lines in the application.properties file:

logging.level.org.springframework=DEBUG
logging.level.com.demo=INFO

20.