In this article I will write about the new Collections APIs introduced in Java 6.0. Mustang has few interesting changes in the Collections APIs, one amoung them is the Deque. Deque is used for the Bi-Directional traversal. It has different implementations including BlockingDeque,ArrayDeque,etc. I will talk about the Deque and its various implementation, also few more changes in the Collectiona API in Java 6.0.
Java 6.0 New Collection APIs an Overview
The following are the new collection APIs introduced in Java 6.0. I listes them as Interfaces and classes.
New Interfaces
Deque
BlockingDeque
NavigableSet
NavigableMap
New Classes
ArrayDeque
LinkedBlockingDeque
ConcurrentSkipListSet
ConcurrentSkipListMap
AbstractMap.SimpleEntry
AbstractMap.SimpleImmutableEntry
Updated Classes in Java 6.0
LinkedList
TreeSet
TreeMap
Collections
Deque and ArrayDeque
Deque is the abbreviation of “Double Ended Queue”. A Collection that allows us to add (or) remove elements at both ends. Deque supports total size of collection for both fixed and unspecified size limits.
Deque implementation can be used as Stack(Last in first out ) or Queue(First in First Out).For each insertion, retrieval and removal of elements from deque there exists methods in 2 flavours. One will throw exception if it fails in an operation and another one returns status or special value for each operation.
Operation Special value method Exception throwing method
Insertion at head offerFirst(e) addFirst(e)
Removal at head pollFirst() removeFirst()
Retrieval at Head
peekFirst() getFirst()
Insertion at Tail offerLast(e) addLast(e)
Removal at Tail pollLast() removeLast()
Retrieval at Tail
peekLast() getLast()
Implementation of Deque doesn’t require preventing the insertion of null, but when we are using special value method null is return to indicate that collection is empty. So it is recommendable not to allow insertion of null.
ArrayDeque is a class that implements Deque. It has no capacity restrictions. It will perform faster than stack when used as stack and faster than linked list when used as queue. ArrayDeque is not thread Safe. The following example explains how to write program using ArrayDeque.
Example
import java.util.ArrayDeque; import java.util.Iterator; public class DequeExample { public static void main(String as[]) { ArrayDeque adObj = new ArrayDeque(); //Insertion by using various methods adObj.add("Oracle"); adObj.addFirst("DB2"); adObj.offerFirst("MySQL"); //returns boolean - true R false adObj.offerLast("Postgres"); //returns boolean - true R false //Retrievals System.out.println("Retrieving First Element :" + adObj.peekFirst()); System.out.println("Retrieving Last Element :"+ adObj.peekLast()); //Removals System.out.println("Removing First Element :"+ adObj.pollFirst()); System.out.println("Removing Last Element :"+ adObj.pollLast()); //Reverse traversal System.out.println("Remaining Elements :"); Iterator it = adObj.descendingIterator(); while(it.hasNext()) { System.out.println(it.next()); } } }Output:
Retrieving First Element :MySQL Retrieving Last Element :Postgres Removing First Element :MySQL Removing Last Element :Postgres Remaining Elements : Oracle DB2BlockingDeque and LinkedBlockingDeque
A BlockingDeque is similar to Deque and provides additionally functionality. When we tries to insert an element in a BlockingDeque, which is already full, it can wait till the space becomes available to insert an element. We can also specify the time limit for waiting.
BlockingDeque methods available in four flavours
Methods throws exception
Methods returns special value
Methods that blocks(Waits indefinitely for space to available)
Methods that times out(Waits for a given time for space to available)
Operation Special Value Throws Exception Blocks Times out
Insertion at head addFirst(e) offerFirst(e) putFirst(e) offerFirst(e,time,unit)
Removal from head removefirst() pollFirst() takeFirst() takeFirst(time,unit)
Retrieval from head getFirst() peekfirst() NA NA
Insertion at tail addLast(e) offerLast(e) putLast(e) offerLast(e,time,unit)
Removal from tail removeLast() pollLast() takeLast() takeLast(time,unit)
Retrieval from tail getLast() peekLast() NA NA
A LinkedBlockingDeque is a Collection class, which implements BlockingDeque interface in which we can specify maximum capacity if we want.If we did not specify the capacity then maximum capacity will be Integer.MAX_VALUE.
import java.util.concurrent.*; class BlockingDequeExample implements Runnable { LinkedBlockingDeque lbd = new LinkedBlockingDeque(1); volatile boolean b = true; public void run() { try { /*First thread once enters into the block it modifies instance variable b to false and prevents second thread to enter into the block */ if(b) { b = false; Thread.sleep(5000);//Makes the Thread to sleep for 5 seconds System.out.println("Removing "+lbd.peek()); lbd.poll();//Removing an element from collection } else { System.out.println("Waiting "); /*This method makes to wait till the first thread removes an elements*/ lbd.put("B"); System.out.println("Inserted "+lbd.peek()); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { BlockingDequeExample bdeObj = new BlockingDequeExample(); bdeObj.lbd.offer("A"); System.out.println("Inserted "+bdeObj.lbd.peek()); Thread tMainObj = new Thread(bdeObj); tMainObj.start(); Thread tSubObj = new Thread(bdeObj); tSubObj.start(); } }Output:
Inserted A Waiting Removing A Inserted B NavigableSet and ConcurrentSkipListSet
Suppose we have a requirement, from sorted set elements [5,10,15,20] we want few things like this
Retrieve the element which is immediately greater than or lower than element 15
Retrieve all elements greater than or lower than 10
With the help of existing methods we need to take few risks to achieve them. But with NavigableSet methods it becomes just a method call.NavigableSet methods used to return the closest matches of elements for the given elements in the collection. ConcurrentSkipListSet is one of the class that implements NavigableSet.
Example
import java.util.concurrent.*; import java.util.*; class SkipListSetTest { public static void main(String[] args) { ConcurrentSkipListSet csls = new ConcurrentSkipListSet(); csls.add(15); csls.add(20); csls.add(5); csls.add(10); System.out.println("Elements in the collections are"); for(Integer i: csls) { System.out.println(i); } /* Retrieve immediate element less than or equal to the given element */ System.out.println("Floor "+csls.floor(12)); /* Retrieve immediate element greater than or equal to the given element */ System.out.println("Ceiling "+csls.ceiling(12)); /* Retrieve immediate element less than the given element */ System.out.println("Lower "+csls.lower(10)); /* Retrieve immediate element greater than the given element */ System.out.println("heigher "+csls.higher(10)); System.out.println("Head Elements "); Set cslsHeadView = csls.headSet(10); //HeadSet excludes the given element for(Integer i: cslsHeadView) { System.out.println(i); } Set cslsTailView = csls.tailSet(10); //TailSet includes the given element System.out.println("Tail Elements"); for(Integer i: cslsTailView) { System.out.println(i); } } }Output:
Elements in the collections are 5 10 15 20 Floor 10 Ceiling 15 Lower 5 heigher 15 Head Elements 5 Tail Elements 10 15 20NavigableMap and ConcurrentSkipListMap
NaviagableMap is similar to NaviagableSet. In NavigableSet, methods use to return values, but in NaviagableMap methods used to return the key,value pair.ConcurrentSkipListMap is the one of the class which implements NaviagableMap.
import java.util.*; import java.util.concurrent.*; class NavigableMapExample { public static void main(String[] args) { NavigableMap nm = new ConcurrentSkipListMap(); nm.put(1,"One"); nm.put(2,"Two"); nm.put(3,"Three"); nm.put(4,"Four"); nm.put(5,"Five"); /* Retrieves the key,value pair immediately lesser than the given key */ Map.Entry ae = nm.lowerEntry(5); /* Map.Entry is a Static interface nested inside Map interface,just use to hold key and value */ System.out.println("Key" + ae.getKey()); System.out.println("Value"+ ae.getValue()); /* Retrieves key,value pairs equal to and greater then the given key */ SortedMap mm = nm.tailMap(3); Set s = mm.keySet(); System.out.println("Tail elements are"); for(Integer i:s) { System.out.println("Key "+ i + "Value "+ mm.get(i)); } } }output
Key 4 Value Four Tail elements are Key 3 Value Three Key 4 Value Four Key 5 Value FiveNotes :
floorEntry method retrieves less than or equal to the givenkey (or) null
lowerEntry method retrieves always less than the givenkey (or) null
headMap method retrieves all elements less than the givenkey
tailMap method retrieves all elements greater than or equal to the givenkey
AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry
AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry are a static classes nested inside abstractMap class.The instance of this classes use to hold the key,value pair of one single entry in a Map.The difference between these two classes is that former one allow us to set the value and later one if we try to set the value, it throws UnsupportedOperationException
Modified classes
Classes are modified to implement the new interfaces in the existing classes.LinkedList is modified to implement Deque. TreeSet is modified to implement NavigableSet.TreeMap is modified to implement NavigableMap.In Collections 2 new methods newSetFromMap and asLifoQueue are added.
Conclusion
With java6.0 collections bi- directional traversal becomes easier and retrieval of elements in our desired way also possible. Some attention is also given towards Concurrent operations in Collection.
No comments:
Post a Comment