Category Archives: Java

Updating Java version in Linux

Recently I upgraded my Java version from 9 to 10 on a Linux machine. I was able to set JAVA_Home in .bashrc file properly but version did not get updated when checked java -version on shell.

Following commands helped to change the system’s Java version

sudo update-alternatives --install "/usr/bin/java" "java" "/path/to/jdk-10.0.1/bin/java" 1

And then

sudo update-alternatives --config java

This showed all the Java versions available and I was able to choose correct version i.e. 10.
Similary executed same commands for java compiler.

sudo update-alternatives --install "/usr/bin/java" "java" "/path/to/jdk-10.0.1/bin/javac" 1
sudo update-alternatives --config javac

Features in Java 9

Java 9 might not be adding major changes like Java 8 which had features like Lambda or Streams or Interface modification, but it does have some good additions.

JShell: If you have worked in python or ruby, you might be aware of shell features these languages provide to quickly run and analyze commands and snippets. Java has come up with similar shell as JShell in Java 9 where you can evaluate the system.

Java Modules/ Jigsaw: Java has taken further step towards modularization. You can define your application in forms of modules and tell JVM what all modules will be used by current module, and what all modules will be exposed which can be used by others.

Private Methods in Interfaces: Java 8 gave us liberty to add method definitions in form of static and default implementations. With Java 9, one can add private methods to help us with organising our code better.

Additional Reads

http://www.baeldung.com/new-java-9
https://www.pluralsight.com/blog/software-development/java-9-new-features

Features added in Java 8

I have already talked about 2 most important features added in Java 8 in my last posts, i.e. Lambda and Streams. Apart from these there were few interesting additions.

Method definition in interfaces: For long time, Java has avoided multiple inheritance due to dreaded diamond problem. They had given us interfaces which did not had method definition, which could have been implemented by a class in multiple numbers. Now, Java has relieved the restriction a bit by allowing static and default methods definition in interfaces.
What about multiple inheritance diamond problem? Well if compiler cannot decide which implementation to use it will thrown an exception.

ForEach: For Collections like Lists, instead of creating an explicit iterator one can use forEach.

Optional: There can be a situation when a method can return null, in such situations the value can be saved in optional class.

Good reads: https://www.journaldev.com/2389/java-8-features-with-examples
http://www.baeldung.com/java-8-new-features

Lambda expressions in Java

Lambda expressions in java is a way to implement functional interfaces. Functional interface is the one which only has single unimplemented method. This gives us freedom from creating a class or anonymous class. In addition Lambdas can be used with streams.

Here is an example. Download the code here

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Jaba8Lambda {

	interface Operations{
		public int operate(int a, int b);
	}
	
	public static void main(String s[]) {
		System.out.println("Welcome to Lambdas");
		
		// A simplest form of lambda, same interface, multiple implementations without a class
		Operations sum = (int a, int b)->a+b;
		Operations multiple = (int a, int b)->a*b;
		
		//Java8Lambda obj= new Jaba8Lambda();
		int mysum = sum.operate(2, 3);
		System.out.println(mysum);
		int myproduct = multiple.operate(2, 3);
		System.out.println(myproduct);
		
		// Another example using Thread Runnable
		// Earlier you would create a Runnable
		
		Runnable myrun = new Runnable() {
			
			@Override
			public void run() {
				System.out.println("starting:"+Thread.currentThread().getName());
			}
		};
		
		new Thread(myrun).start();
		
		// With Labdas we can do away with anonymous classes
		Runnable myrunLambda = ()->{
			System.out.println("starting:"+Thread.currentThread().getName());
		};
		new Thread(myrunLambda).start();
		
		// Lambdas can be used with streams as well
		List intlist= new ArrayList();
		intlist.add(2);
		intlist.add(7);
		intlist.add(12);
		intlist.add(17);
		Stream stream = intlist.stream(); 
		stream.forEach(i->{
			if(i%2==0) {
				System.out.println(i+" is even.");
			}
		});

	}
}

Java Streams

Java had introduced streams in Java 8 to help us fasten the development by providing ways to perform operations on data streams (collections) without writing bulky code.

In short, stream can be thought of stream or pipeline of data, on which you need to perform some operations. There can be two types of operations, intermediate and terminal. Intermediate operations are the ones which transforms the data in the stream, but the output is still a stream, for example filter or map operations. On the other hand terminal operations are ones which are applied collectively on the stream and output is something other than stream for example sum or reduce methods.

Here is an example usage to make it more clear. Or Download code from git repo

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Java8Streams {
	
	public static void main(String s[]) {
		System.out.println("Welcome to streams!");
		
		//There are multiple ways to create streams
		Stream stream = Stream.of(new Integer[]{1,2,3,4}); 
		Stream intStream = Stream.of(1,2,3,4);


		// Using streams to find sum of a integer list
		List intlist= new ArrayList();
		intlist.add(2);
		intlist.add(7);
		intlist.add(12);
		intlist.add(17);
		Stream streamnew = intlist.stream(); 
		
		// No more looping through the array
		Integer sum = intlist.stream().mapToInt(i->i).sum();
		System.out.println("Sum is :"+sum);
		
		// Lets check if the array contains even number, without looping
		boolean anyEven= intlist.stream().anyMatch(i->i%2==0);
		System.out.println(anyEven);
		
		// Check if all elements are even in the list
		boolean allEven = intlist.stream().allMatch(i->i%2==0);
		System.out.println(allEven);
		
		// Find first even number from the list
		Optional firsteven= intlist.stream().filter(i->i%2==0).findFirst();
		System.out.println(firsteven);
		
		// Now lets sum all even numbers
		int sumeven = intlist.stream().filter(i->i%2==0).mapToInt(i->i).sum();
		System.out.println(sumeven);
		
		// Lets use forEach to do operations on each element, say add a constant number to even numbers and print
		intlist.stream().forEach(i->{
			if(i%2==0) {
				i = i+100;
				System.out.print(i+",");
			}
		});
		System.out.println();
		//Better way to achieve the above
		intlist.stream().filter(i->i%2==0).forEach(i->{
			i = i+100;
			System.out.print(i+",");
		});
		
		System.out.println();
		// Simliar to filter, we gave map function
		List newlist = intlist.stream().map(i->{
			return i+100;
		}).collect(Collectors.toList());
		System.out.println(newlist);
		
		// Use reduce to perform some custom operation
		Optional output = intlist.stream().map(i->{
			return i+10;
		}).reduce((i,j)->{
			return i*j;
		});
		System.out.println(output);
		
	}

}

Java- Call by Reference vs Call by Value

In Java, when we send objects to a method, do they get passed by reference or by value?
Answer is, the reference of object is passed by value. This can be a bit tricky to absorb first. Let us try to understand. Reference in this case is a pointer (just to visualize, as we know there are no pointers in Java) to the object location.

Employee obj = new Employee();
sendToMethod(obj);

When we are sending this obj to a method, the object copy itself does not get sent neither the object reference. It is the copy of obj reference. So think of it like obj is stored at location “HB10”, this “HB10” gets copied and sent to method. Any changes directly made to the object gets reflected back to the calling method, but if reference itself is update, no changes get reflected.

private void sendToMethod(Employee obj)
{
obj.setSalary(100000);// gets reflected
obj = new Exployee(); // we removed reference, so no changes after this will be reflected in calling method.
obj.setDept(“IT”);// does not gets reflected.
}

A more elaborated example code

import java.util.ArrayList;

public class Test {

public static void main(String args[]) {
ArrayList iList = new ArrayList();
iList.add(1);
System.out.println(“\nPrint list Before”);
iList.stream().forEach(x->System.out.print(x+”, “)); // prints 1,
updateMe(iList);
System.out.println(“\nPrint list After”);
iList.stream().forEach(x->System.out.print(x+”, “)); // prints 1, 2,
}
public static void updateMe(ArrayList iList) {
ArrayList jList = new ArrayList();
iList.add(2); //this gets reflected
jList.add(3);
iList = jList; // reference changed, no changes after this are reflected.
iList.add(4);
jList.add(5);
}
}

Node vs Java Comparison

A good read on Node vs Java https://rclayton.silvrback.com/speaking-intelligently-about-java-vs-node-performance. Explains about the way Java and Node code will work to handle load.

My personal opinion is that programming language is just a tool to deliver the final solution. Only in specialized cases, where we know that a particular language has proven history of solving similar kind of problems, hence has sample code, libraries, knowledge base, forums to help, we should consider that as part of solution. Otherwise non-technical reasons like client preferences, team’e expertise will come into picture.

Understanding Maven -2

I had shared a basic understanding of maven sometime back.

http://kamalmeet.com/java/understanding-maven/

Here I will try to get into some more details.

As mentioned earlier we need a pom file for any maven project. POM stands for Project Object Model. It contains configuration details for the project.

To start with we provide basic info such as

<groupId>com.companyname.project-group</groupId>
<artifactId>project</artifactId>
<version>1.0</version>

 
group id: shows project group, say finance
artifact id: within group we will have a unique project name as artifact id say payroll
version: It is the release version e.g. 1.0 or 2.1.2 etc.
repositories: where all the jars, plugins and other artifacts are stored and used by maven.

<repositories>
<repository>
<id>custom.id</id>
<url>http://validrepo.com/mavenrepo</url>
</repository>
</repositories>

Type of repositories

Local Repository: A folder on local machine where all the dependencies are stored. Maven by default creates the repo in user/home directory, this path can be overridden by “localrepository” tag in POM.
Central repository: This is by default provided by maven, and has most of the common jars. No need for a separate configuration for this.
Remote Repository: Developer has an option to provide a repository explicitly, so if a give dependency is not found in central repository, it will be fetched from remote repository.

Dependencies: All the Jar files on which project is dependent and will be downloaded before the build.


<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.2</version>
</dependency>

 

Inject Or Autowired

Sometimes in a Spring framework code, we see the keywords @Inject and @Autowired being used interchangeably. Simply putting it @Autowired is Spring specific annotation for implementing Dependency Injection, whereas @Inject is part of Java EE 6 specification, hence more generic.

JSR 299, Java EE 6 specification, provided a feature called Contexts and Dependency Injection (CDI). http://docs.oracle.com/javaee/6/tutorial/doc/giwhb.html.

JSR 330, more specifically talks about Dependency Injection. https://dzone.com/articles/what-relation-betwe-there

A more elaborated explanation on usage of various DI annotations – http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/#more-2350

Java Best Practices- String Literal Comparison

Whenever we create a String literal or a String constant, Java searches its String pool and if string is found, it will give reference to the String variable. Please note this is true only when we create a literal and not the object, i.e you do String str=”hello” and not String str=new String(“hello”);

Another point of importance is that if you compare string literals using ==, it might work because as mentioned above both the Strings might be refering to same object.

Example

String str=”hello “+”kamal”;
String str1=”hello”;
str1+=” kamal”;
String str2=”hello kamal”;
String str3=”hello kamal”;

System.out.println(str);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
// all above prints hello kamal

System.out.println(str==str1); //false
System.out.println(str==str2); //true
System.out.println(str==str3); //true
System.out.println(str.equals(str1)); //true
System.out.println(str.equals(str2)); //true
System.out.println(str.equals(str3)); //true