A refresher on Multithreading in Java
Category Archives: Java
Java Collection Framework and Generics
As the name suggests, a Java Collection is a collection of objects represented as a single unit. The idea is to provide a set of operations on the logically grouped elements like searching, sorting, etc.

As the image above shows, there are two core interfaces, Collection and Map. The collection further has interfaces for List, Queue, and Set. For each of these interfaces than we have a concrete set of classes implementing the functionality.
Let’s take a very simple example
Collection values = new ArrayList(); values.add(1); values.add(2); values.add("kamal");
We can see collection interface helps us create a new ArrayList, which gives us flexibility over the array where the List can grow during runtime.
But one challenge we can see in the code above is that when we are able to add numbers as well as String to the ArrayList. This is in contrast with the type safety provided by Java. To solve this Java provides us Generics to control over types of elements that can be added to a collection.
Generics Example
class MyClass<T>{ T value; public T getValue() { return value; } public void setValue(T value) { this.value = value; } }
Coming to our previous code for creating collections
Collection<Integer> values = new ArrayList<>(); values.add(1);
In this example, we cannot add a String to values now.
What if we want to get or add into ArrayList at a particular index. List Interface adds these features on top of Collection. As already depicted in the hierarchy, List inherits Collection and then adds features on top of it.
List<Integer> values = new ArrayList<>(); values.add(1); int num = values.get(0);
Iterating over a Collection
There are multiple ways to iterate over a collection
List<Integer> values = new ArrayList<>(); values.add(1); values.add(2); values.add(3); Iterator<Integer> i= values.iterator(); while(i.hasNext()) { System.out.println(i.next()); }
Another way is to use for loop
for(Integer num:values) { System.out.println(num); }
Or we can use Streams
values.stream().forEach(System.out::println)
Comparable vs Comparator
Another important thing one would like to do with the collection is to arrange elements in sorted order. For example, say we have a List created for Student class objects, and we want to arrange based on Roll numbers.
The easiest way is to make the class implement comparable
class Student implements Comparable<Student>{ int rollno; String name; public Student(int rollno, String name) { this.rollno=rollno; this.name=name; } @Override public int compareTo(Student o) { return this.rollno<o.rollno?-1 : (this.rollno==o.rollno)?0:1; } } // In calling code, we can sort list made up of students Collections.sort(list);
There can be cases where it is handy to maintain comparison based on multiple criteria. For example, along with roll number, we want to make sure we can sort the list of students based on names in alphabetical order. In such a case it makes sense to implement Comparator as we can implement multiple comparators based on our need.
class NameComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } } // In calling code, we will send compatator instance Collections.sort(list, new NameComparator());
Getting started with Spring Boot
This is a short tutorial about creating a simple REST webservice with spring boot. This assumes you have basic knowledge of Spring and Java.
To get started we will create a Spring project. The simplest way to do this is to go to http://start.spring.io/ and create a project.
This will give us a blank project on which we can build upon. Import the project as Maven project to Eclipse or any other ID. By default, it will provide a class which will look like
@SpringBootApplication public class NewtestApplication { public static void main(String[] args) { SpringApplication.run(NewtestApplication.class, args); } }
As you can see this is the main class and all the execution starts here. Also, note the @SpringBootApplication annotation. Spring documentation states that
“The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan with their default attributes”
For this example, we will keep it simple and introduce a controller
@RestController public class HelloController { @GetMapping("/sayhello") public String sayHello() { return("Hello"); } }
Finally, Run the main class as a normal Java application, it will automatically start the Spring Boot server at 8080.
We can now access our application at http://localhost:8080/sayhello
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
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 Listintlist= 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 Streamstream = 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[]) {
ArrayListiList = 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(ArrayListiList) {
ArrayListjList = 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.