HTML Java

Java Collection Difference


Traditional Vs. Concurrent Collection


Traditional Collection

AL, LL, Vector, HM etc.

There are some drawbacks in Traditional Collection concurrent collection comes into picture.

Concurrent Collection

CopyOnWriteArrayList, CopyOnWriteArraySet, Concurrent HashMap, etc.


Drawbacks in Traditional Collection

not thread safe :- ArrayList, Set, HashSet, LinkedHashSet, TreeSet, HashMap

but it give better performance than thread Safe collection its faster whenever we use these collections in Multithreading Environment then there is consistency problem comes. And we can say they are not Synchronized.

What do you mean by not thread safe?

It means like arraylist methods suppose add() are accessing in multithreading environment by multiple thread at a time. Then inconsistent result will come.


Thread Safe Collections: Vector, HashTable, synchronizedList() but its performanc is not good and slower than thread Safe collection .

synchronizedList() is a method of Collections class by the help of this method we can make our ArrayList Synchronized.


If multiple threads perform read operation not an issue. But issue comes when thread perform write operation.


fail safe vs fail fast

Example

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class ConcurrentDemo {

public static void main(String[] args) {

Map hmap = new HashMap();
hmap.put("101","coders");
hmap.put("102","arts");

Set set = hmap.entrySet();
Iterator itr = set.iterator();
while(itr.hasNext()) {
Map.Entry m = (Map.Entry)itr.next();
//hmap.put("103","ankit”);
System.out.println(m.getKey()+":"+m.getValue());
}
}
}

Output:

101:coders


Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$EntryIterator.next(HashMap.java:1476)
at java.util.HashMap$EntryIterator.next(HashMap.java:1474)
at ConcurrentDemo.main(ConcurrentDemo.java:16)

why ? Because while reading the element from the hash map you are adding the element into it. So thats why this ConcurrentModificationException Occurs and this concept is called fail fast. Other means of fail fast is like hashMap which is not synchornized and at the time of reading the data you are writing as well and at that time program will fail. We can solve this problem create ConcurrentHashMap instead of HashMap. Then

Output:

101: coders
102: arts
103: ankit

And when using the ConcurrentHashMap we our program runs successfully this called fast safe.


Another Example of This ConcurrentModificationException

Example

import java.util.ArrayList;

public class ExampleOfConcurrentModificationException extends Thread {

static ArrayList arrayList = new ArrayList();

public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
arrayList.add(5);
}

public static void main(String[] args) {
arrayList.add(1);
arrayList.add(2);
ExampleOfConcurrentModificationException t1 = new ExampleOfConcurrentModificationException();
t1.start();

for (Integer list : arrayList) {
System.out.println(list);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Output:

1

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at ExampleOfConcurrentModificationException.main(ExampleOfConcurrentModificationException.java:23)


because arraylist method is not Synchronized thats why this Exception occurs like reading element from the arraylist is running on different thread and add element into the arrayList is running on different thread. To avoid this Exception you can use CopyOnWriteArrayList instead ArrayList.

Example

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class LambdaDemo {

public static void main(String[] args) {
Student s1 = new Student(1,"ankit");
Student s2 = new Student(2,"alok");
Student s3 = new Student(3,"amit");
Student s4 = new Student(4,"ankita");

List stuList = new ArrayList();
stuList.add(s1);
stuList.add(s2);
stuList.add(s3);
stuList.add(s4);

Collections.sort(stuList);
}
}

When we use Collections.sort(stuList) then it will get confuse that on which basis should i sort on roll or by name . So we can’t use so to compare two objects value we have to use either Comparators or Comparable but its very long procedure we have to implements one of it. In user defined class like in my case Student class and we have to override method of compareTo() and write logic for the comparison but we can solve it by lamdaexpression like this ,


Example

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

public class LambdaDemo {

public static void main(String[] args) {

Student s1 = new Student(1,"ankit");
Student s2 = new Student(2,"alok");
Student s3 = new Student(3,"amit");
Student s4 = new Student(4,"ankita");

List stuList = new ArrayList();
stuList.add(s1);
stuList.add(s2);
stuList.add(s3);
stuList.add(s4);

Collections.sort(stuList,(a,b)->{
return a.name.compareTo(b.name);
});

for(Student s : stuList) {
System.out.println(s.name+" "+s.roll);
}

Stream filter_data = stuList.stream().filter(a->a.roll< 4);
filter_data.forEach(a->System.out.println(a.roll+" "+a.name));

}

}

Output:

alok 2
amit 3
ankit 1
ankita 4
2 alok
3 amit
1 ankit


In the above problem we use Stream class API this is used when large data we have in our application and we want to display those data under any conditions. Like age< 24 and many things.

We can’t create an object of Stream class we call method .stream() and it returns stream type data again and we again filter on it.


Queue(i) Interface

In this data is stored in FIFO manner its implementing class PriorityQueue(c), LinkedList, ArrayDeque and child interface is Deque(i).


When we print object then We get reference id but when we create an object of an arrayList and then we print that object then reference id is not printed its print “[]”?

when we are creating an object of any class so implicit reference id is generated into the memory but when we create an object of an arrayList then we print we get “[]” because implicitly every class is a child class of Object class and when we create an object of any class then toString method of Object class is run automatically toTring method is created refernce id for any object or we can override it also but in case of arraylist it means its override to String method and return as a string “[]” when its object is printed.

Example

import java.util.ArrayList;

public class Question1 {
public static void main(String[] args) {
Student s = new Student("ankit");
System.out.println(s);

ArrayList arrayList = new ArrayList();
System.out.println(arrayList);
}
}

Output:

Student@4aa298b7
[]


Performance of ArrayList Vs Linked List

ArrayList take more time to add element but less time to get elements LinkedList take less time to add element but more time to get elements.

We should use arraylist when we have only fetch the data because it fetch the data faster than LinkedList.

If we have to manipulate on data (remove(),get()) we should go with Linked List

Example

import java.util.ArrayList;
import java.util.LinkedList;

public class LinkedListVsArrayList {

public static void main(String[] args) {
long start_Time, end_Time;

ArrayList arrayList = new ArrayList();
LinkedList linkedList = new LinkedList();

start_Time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
arrayList.add(i);
}

end_Time = System.nanoTime();
System.out.println("Time take to add element in the ArrayList : " + (end_Time - start_Time));

start_Time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
linkedList.add(i);
}

end_Time = System.nanoTime();
System.out.println("Time take to add element in the LinkedList : " + (end_Time - start_Time));

start_Time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
arrayList.get(i);
}

end_Time = System.nanoTime();
System.out.println("Time take to get element in the ArrayList : " + (end_Time - start_Time));

start_Time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
linkedList.get(i);
}

end_Time = System.nanoTime();
System.out.println("Time take to get element in the LinkedList : " + (end_Time - start_Time));

}

}

Output:

Time take to add element in the ArrayList : 4716862
Time take to add element in the LinkedList : 2580848
Time take to get element in the ArrayList : 1149295
Time take to get element in the LinkedList : 83877911


Set Interface

No duplicacy No Order and inherit Collection interface but it change add method like that no duplicate element allowed.


HashSet

HashSet is a concrete class which providing the implementation of Set Interface an object of this class is responsible to creating a hash table in a memory. HashSet uses Hashing technique to store unique data. Null element is permitted and it’s non-synchronized and its default constructor which store the elements its create hashtable of 16 bucket and by default .75 loadfactor it contains. Hashtable is array of LinkedList and each list is called Bucket.

Bucket 0 to bucket 15

Note: whenever we create any object in java then hashcode is generated into the memory.

Whenever add method add object n then internally so object hashcode return it use hashing techniques take hashcode of the object and divide by the total no of bucket and what remainder it gets that will be the bucket index where that object is going to store. That’s why ordering is not done in this .we don’t know the newly created object which is going to store on which index.

No delicacy why : add method internally call contains method and contains method internally call equals method and equal methods check that the object which is going to add is it already present in the bucket it compare content wise if its present then equals method returns true or else return false. If its true then element is not going to add, and 1 bucket can store only 1 element.

You can give load factor between 0 to 1 only