Archive

Archive for the ‘Java’ Category

Java – HashMap in-detail explanation

HashMap works based on hashing algorithm, As per Java doc HashMap has below four constructors,

Constructor Description
HashMap​()
Constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
HashMap​(int initialCapacity)
Constructs an empty HashMap with the specified initial capacity and the default load factor (0.75).
HashMap​(int initialCapacity,
float loadFactor)
Constructs an empty HashMap with the specified initial capacity and load factor.
HashMap​(Map<? extends K,? extends V> m)
Constructs a new HashMap with the same mappings as the specified Map.

Let’s write simple java program, to examine how Map works internally

  1. Create a simple Map and add one key and value to it

public static void main(String[] args) {

Map<Integer, String> map = new HashMap<>();

map.put(1, "Java");

}

We just created Simple Map, which takes key as Integer and Value as String, and added “1” as Key and “Java” as value. By using eclipse debug feature, lets see what’s inside the map

HashMap-one

It created 16 blocks(0-15) and inserted 1st block with key as Integer “1” and Value as String “Java”. Please check the red box, rest all boxes initialized with  null.

2. Add second key and value to the same map

public static void main(String[] args) {

Map<Integer, String> map = new HashMap<>();

map.put(1, "Java");

map.put(2, "Angular");

}

lets see the map in eclipse debug again

HashMap-two

Now the map contains two keys (1,2) and two values (“Java”, “Angular”) as expected, but the keys are added exactly at 1st block and 2nd block respectively, why?

because as we know Map works based on hashing algorithm, whenever we insert key to map, it calls the Object#hashcode() method, based on the value of hashCode(), it will insert the key into that block.

In above case, Integer class overrides the hashCode with its primitive int value, thats why (1,java) got stored in 1st block and (2,Angular) got store in 2nd block.

3. Lets do the same experiment with our own Class

Create a simple Employee class like below

private static class Employee{
int id;
String name;

Employee(int id, String name){
this.id = id;
this.name = name;
}
}

Use this class as Key to the map and examine the same way


public static void main(String[] args) {
Map<Employee, String> map = new HashMap<>(10);
map.put(new Employee(1, "Ramesh"), "Java");
map.put(new Employee(2, "Sathish"), "Angular");
}

We have added two keys as Employee objects and Values as just strings, lets see in which block the keys got stored this time

HashMap-three

This time, it stored in 8th block and 14th block(why? simple answer because of hashCode of Employee objects), to confirm this, lets override hashCode() of Employee to constant value and check the map. If our analysis correct it has to store all the key’s in the same block.

Update Employee class accordingly

private static class Employee{
int id;
String name;
Employee(int id, String name){
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
return 10;
}
}

We dont need to change anything to our map, lets see now where the keys got stored

HashMap-four

Yes, only 10th block got filled with two objects, why? because both employee objects returned the same hashCode (i.e 10). But how does Map recognized those two objects are not duplicate? As we know internally Map#Key is an entrySet(java.util.Set) it called equals method to verify whether the key is duplicate or not.

While retrieving the value from Map also, first it will check the hashCode of the given key and based on that it will go to that block, after finding the block it will call equals() to get the exact value.

So overriding the hashCode() to constant is not at all recommendable. and when we override the hashCode() we should not forget to override the equals() method as well(i.e hashCode()/equals() contract).

 

 

Advertisements
Categories: Java

Java9 : ServiceLoader

java.util.ServiceLoader class loads the service providers/implementations at run time. While compile time ServiceLoader just need to know Service interface. With the Java9 modularity, we can add service implementation modules dynamically at run time, And Application can have new implementation with out effecting anything,

lets check with an example, create a module EventsAPI with an interface  EventService.java

EventsAPI/EventService.java


package events.api;

public interface EventService {
 public String getName();
}

EventsAPI/module-info.java


module events.api {
 exports events.api;
}

Create an implementation to the EventService interface in another module called FacebookEvents

FacebookEvents/FacebookEventService.java

package events.api.facebook;
import events.api.EventService;

public class FacebookEventService implements EventService{

 public FacebookEventService() {
     System.out.println("FacebookEventService Constructor");
 }
 public String getName() {
    return "facebook events";
 }
}

 

FacebookEvents/module-info.java

module events.api.facebook {
 requires events.api;

 provides events.api.EventService
 with events.api.facebook.FacebookEventService;
}

 

FacebookEvents module requires EventsAPI, because it need to have access to EventService.java interface.

And it provides EventService implementation with FacebookEventService.

Lets create a Client module EventsClient to consume EventsAPI

EventsClient/module-info.java

 

module client.calendar {
requires events.api;
uses events.api.EventService;
}

We are going to use ServiceLoader to find the implementations of EventService interface, here ServiceLoader requires uses keyword on EventService, otherwise compiler will throw an error.

Finally Client Test class

EventsClient/Calendar.java

package client.calendar;
import java.util.ServiceLoader;
import events.api.EventService;

public class Calendar {
public static void main(String[] args) {
System.out.println("Calendar events..!!!");
ServiceLoader<EventService> events = ServiceLoader.load(EventService.class);

for(EventService event : events) {
System.out.println(event.hashCode() + " : " +event.getName());
}
events.reload();
for(EventService event : events) {
System.out.println(event.hashCode() + " : " +event.getName());
}
}
}

In the EventsClient module, we din’t mention anything about FacebookEvents module, while running the above Calendar.java add FacebookEvents module, the output will be

output

Calendar events..!!!
FacebookEventService Constructor
1627960023 : facebook events
FacebookEventService Constructor
745160567 : facebook events

ServiceLoader found the EventService implementation FacebookEventService and showed the output, lets add another implementation to the EventService interface and examine the output from above client

TwitterEvents/module-info.java


module events.api.twitter {
requires events.api;
provides events.api.EventService
with events.api.twitter.TwitterEventService;
}

same as FacebookEventService, will have TwitterEventService which will implement EventService interface

TwitterEvents/TwitterEventService.java


package events.api.twitter;

import events.api.EventService;

public class TwitterEventService implements EventService{

public TwitterEventService() {
System.out.println("TwitterEventService Constructor");
}

public String getName() {
return "twitter events";
}
}

Run the EventsClient/Calendar.java by adding TwitterEvents module on the modulepath, output as follows

Calendar events..!!!
TwitterEventService Constructor
249515771 : twitter events
FacebookEventService Constructor
1627960023 : facebook events
TwitterEventService Constructor
321142942 : twitter events
FacebookEventService Constructor
745160567 : facebook events

We have just added TwitterEvents module in the run time, ServiceLoader is able to load the TwitterEventService and gave the desired output.

Source code is available at https://github.com/rameshcharykotha/java9practice

Thanks for reading..!!

Categories: Java, Java9

Java9: Welcome to Module world

Java 9 has been released on September 21 officially, Eclipse is supporting Java 9 from  Eclipse Oxygen.1a (4.7.1a), Lets jump into module world..!!!

Download Java 9 from here, and add it to Eclipse Installed JRE’s as below

Eclipse - JRE

That’s it, we are good to write Java 9 module programs in Eclipse.

  1. Create First java project and add module-info.java to it, right click on the project java9-module-info

module-info.java

module first {

}

Module should start with keyword module followed by its name. currently it doesn’t requires anything or it doesn’t export anything.

2. Let’s create Second java project,

module-info.java

module second {
exports second; --<em> second module is exporting a package "second"</em>
}

Second.java — create a simple Java class with public sayHello() method in second package

package second;

public class Second {
public void sayHello() {
System.out.println("Welcome to module world..!!");
}
}

Second java class will be available to other modules, as it is exporting second package.

3. Update first module –  module-info.java as below

module first {
requires second;
}

Now first module requires second module, but it will fail with module can not be resolved compilation error

“second cannot be resolved to a module”

we need to add second module as dependency to first module.

module-path

Check the new thing called modulepath

3. Create FirstTest.java in first package as below

package first;

import second.Second; // we are accessing Second.java from second module

public class FirstTest {

public static void main(String[] args) {
Second second = new Second();
second.sayHello();
}
}

Running the above would print “Welcome to module world..!!

source code can be found at Github

Categories: Java, Java9

Java 8 : Predicate example

March 23, 2014 1 comment

Java 8 introduces functional style of programming.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

Here we have list with integers, if we want to print even numbers from it, will write something like below


public List<Integer> printEvenNumbers(List<Integer> list){

List<Integer> result = new ArrayList<Integer>();

for(Integer i : list){

if(i%2 == 0){

result.add(i);

}

}

return result;

}

Now if we want to print odd numbers, so will write something like below


public List<Integer> printOddNumbers(List<Integer> list){

List<Integer> result = new ArrayList<Integer>();

for(Integer i : list){

if(i%2 != 0){

result.add(i);

}

}

return result;

}

Except the if condition, everything is copy pasted. Again if we want the numbers only divisible by 3, again we have to copy paste entire code just by changing the if condition.

If we have a chance to pass the if condition as a argument to method, then we would have achieved both requirements with only one method, for this java 8 introduced an interface called java.util.function.Predicate<T>

Complete example:


import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class PredicateTest{

public static void main(String [] a)  {

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

System.out.println("Print all numbers:");
condition(list, (n)->true);

System.out.println("Print no numbers:");
condition(list, (n)->false);

System.out.println("Print even numbers:");
condition(list, (n)-> n%2 == 0 );

System.out.println("Print odd numbers:");
condition(list, (n)-> n%2 == 1 );

System.out.println("Print numbers greater than 5:");
condition(list, (n)-> n > 5 );

}

public static void condition(List<Integer> list, Predicate<Integer> predicate) {
for(Integer n: list)  {
if(predicate.test(n)) {
System.out.println(n + " ");
}
}
}
}

Categories: Java

Java 8 : Double Colon operator

March 17, 2014 1 comment

Double Colon operator introduced in Java 8, We use it as method reference.

Syntax : ClassName::MethodName

for example, if we want to print a list :


List<String> strings = Arrays.asList("one","two");

strings.forEach(System.out::println);

here forEach is a new method added to the List interface in java 8. System.out is the PrintStream Class and println is method in it.

Complete Example:


import java.util.*;
import java.util.stream.*;

public class DoubleColon{

public static void display(String name){
System.out.println("Name : "+name);
}
public static void main(String[] args){
List<String> names = Arrays.asList("one","two","three");
names.forEach(DoubleColon::display);
}
}

Categories: Java

Java 8 : Functional Interface Example

March 16, 2014 10 comments

To Support lambda expressions in Java 8, they introduced Functional Interfaces.

An interface which has Single Abstract Method can be called as Functional Interface.

Runnable, Comparator,Cloneable are some of the examples for Functional Interface. We can implement these Functional Interfaces by using Lambda expression.

For example:

Thread t =new Thread(new Runnable(){
   public void run(){
     System.out.println("Runnable implemented by using Lambda Expression");
   }
});

This is the old way of creating a Thread.

As Runnable is having Single Abstract Method, we can consider this as a Functional Interface and we can use Lambda expression like below.

Thread t = new Thread(()->{
   System.out.println("Runnable implemented by using Lambda Expression");
});

Here instead of passing Runnable object we just passed lambda expression.

Declaring our own Functional Interfaces:

We can declare our own Functional Interface by defining Single Abstract Method in interface.

public interface FunctionalInterfaceTest{
void display();
}
//Test class to implement above interface
public class FunctionInterfaceTestImpl {
      public static void main(String[] args){
     //Old way using anonymous inner class
     FunctionalInterfaceTest fit = new FunctionalInterfaceTest(){
        public void display(){
           System.out.println("Display from old way");
        }};
     fit.display();//outputs: Display from old way
     //Using lambda expression
     FunctionalInterfaceTest newWay = () -> {System.out.println("Display from new Lambda Expression");}
        newWay.display();//outputs : Display from new Lambda Expression
     }
}

We can annotate with @FunctionalInterface annotation, to tell compile time errors. It is optional

for ex:

@FunctionalInterface
public interface FunctionalInterfaceTest{
   void display();
   void anotherDisplay();//shows an error, FunctionalInterface should have only one abstarct method.
}

Default Method:

Functional interface can not have more than one abstract method but it can have more than one default methods.

Default methods are introduced in Java 8, to add new methods to interface with out disturbing the implemented classes.

interface DefaultInterfaceTest{
  void show();
  default void display(){
     System.out.println("Default method from interface can have body..!");
  }
}
public class DefaultInterfaceTestImpl implements DefaultInterfaceTest{
   public void show(){
         System.out.println("show method");
   }
   //we dont need to provide any implementation to default method.
   public static void main(String[] args){
          DefaultInterfaceTest obj = new DefaultInterfaceTestImpl();
          obj.show();//out puts: show method
          obj.display();//outputs : Default method from interface can have body..!
        }
}

Main use of default method is with out forcing the implemented class , we can add a method to an interface.

Multiple Inheritance:

If the same default method is there in two interfaces and one class is implementing that interface, then it will throw an error.


//Normal interface with show method

interface Test{

  default void show(){
     System.out.println("show from Test");
  }

}

//Another interface with same show method

interface AnotherTest{

   default void show(){
      System.out.println("show from Test");
   }

}

//Main class to implement above two interfaces

class Main implements Test, AnotherTest{
//here is an ambiguity which show method has to inherit here
}

This class wont compile because there is an ambiguity between Test, AnotherTest interfaces show() method, to resolve this we need to override show() method to Main Class.


class Main implements Test, AnotherTest{

   void show(){
      System.out.println("Main show method");
   }

}

Categories: Java

Java 8 : Lambda Example

March 16, 2014 1 comment

Lambda Expressions:

Lambda expressions are new and important feature of Java 8. They provide a clear way to represent one method interface using lambda expression. And they provide easy way to access Collection libraries for iterating, filter and extract data.

Example :

Syntax : (arg1, arg2) -> {body}

For Ex:


(int a, int b) -> {  return a + b; }

() -> System.out.println("Hello World");

(String s) -> { System.out.println(s); }

//Old way of iterating Collection

List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

for(Integer n: list) {

System.out.println(n);

}

//New way with lambda:

List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

list.forEach(n -> System.out.println(n));

Rules:

  1. It can have zero or more number of arguments.
  2. Parameters are separated by using comma
  3. Empty parenthesis are used to represent empty parameters eg : () -> System.out.println(“Hello World”);
  4. Curly braces for body is not mandatory if it contains only single statement, other wise it should enclosed with curly braces.

Program:


interface TestInterface{
void display();
}
public class TestInterfaceImpl{

public static void main(String[] args){
TestInterface li = new TestInterface(){
public void display(){
System.out.println("Hello World");
}
};
li.display();
}
}

Here we used anonymous class to implement TestInterface and this interface has only one method, by using lambda expression without using anonymous class we can call the display() method


interface TestInterface{
void display();
}
public class TestInterfaceImpl{

public static void main(String[] args){
//Old way:
TestInterface old = new TestInterface(){
public void display(){
System.out.println("Old : Display method called!");
}
};
old.display();
//New way with Lambda expression
TestInterface li = () -> System.out.println("New : Display method called !");
li.display();

}
}

This approach we regularly use in Java Swing, while adding an action to Swing Component we use ActionListener actionPerformed() method, ActionListener  is an interface which has only one method called actionPerformed(),


//old way:
button.addActionListener(new ActionListener()){
public void actionPerformed(ActionEvent e){
System.out.println("The button was clicked using old fashion code!");
}
}
//New way:
button.addActionListener( (e) -> {
System.out.println("The button was clicked. From lambda expressions !");
});

java.util.Runnable also has only one method public void run(), this also we can represent using lambda


//old way

Runnable r = new Runnable(){

public void run(){

System.out.println("Runnable run method");

}

}

//New way with lambda expression

Runnable r = ()->System.out.println("Runnable run method");

//So we can create Thread object like below

Thread t = new Thread(()->{System.out.println("Runnable run method from lambda")});

Any interface which has only one method can be used with lambda expression instead of old anonymous inner class.

Thanks for reading.

Categories: Java