Archive for the ‘Collection Framework’ Category

Consider that you have a List of Employee Objects. If you want to find the list of employee id’s from the list, then you have to use the collect() method of CollectionUtils class provided by commons-collections jar.

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.TransformerUtils;

List<Employee> managers = new ArrayList<Employee>();
Collection<Long> managerIDs = CollectionUtils.collect(managers,                                            TransformerUtils.invokerTransformer(“getId”));

 

 

 

 

Advertisements

We are making use of the isWhitespace(char ch) method of the java.lang.Character class.

public static String ltrim(String s) {
int i = 0;
while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
i++;
}
return s.substring(i);
}

public static String rtrim(String s) {
int i = s.length() – 1;
while (i > 0 && Character.isWhitespace(s.charAt(i))) {
i–;
}
return s.substring(0, i + 1);
}

Unicode Surrogate characters do not represent characters by themselves, but are used in the representation of supplementary characters in the UTF-16 encoding.
A char value is a surrogate code unit if and only if it is either a low-surrogate code unit or a high-surrogate code unit.

java.lang.Character class provides a method

public static boolean isSurrogate(char ch)

ch – is the character that you have to check for
This method returns true if the char value is between MIN_SURROGATE and MAX_SURROGATE inclusive; false otherwise.

MIN_SURROGATE and MAX_SURROGATE are already defined in Character class

public static final char MIN_SURROGATE = “\uDFFF”;
public static final char MIN_SURROGATE = “\uD800”;

Example :

You can try either of the following 2 code snippets

public static String trimUnicodeSurrogateCharacters(String text) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (!Character.isSurrogate(ch)) {
sb.append(ch);
}
}
return sb.toString();
}

OR

public static String trimUnicodeSurrogateCharacters(String text) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (!Character.isHighSurrogate(ch) && !Character.isLowSurrogate(ch)) {
sb.append(ch);
}
}
return sb.toString();
}

 

 

Let’s first take a look at the interfaces which the ArrayList and LinkedList implement.

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable,Serializable
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Queue<E> Cloneable, Serializable

ArrayList

Now for some implementation notes. The ArrayList is actually encapsulating an actualy Array, an Object[]. When you instanciate ArrayList, an array is created, and when you add values into it, the array changes its size accordingly. This gives you strengths and weaknesses:

  • Fast Random Access

You can perform random access without fearing for performence. Calling get(int) will just access the underlying array

  • Adding values might be slow When you don’t know the amount of values the array will contain when you create it, a lot of shifting is going to be done in the memory space when the ArrayList manipulates its internal array.
  • Slow manipulation When you’ll want to add a value randomly inside the array, between two already existing values, the array will have to start moving all the values one spot to the right in order to let that happen.

LinkedList

The LinkedList is implemented using nodes linked to each other. Each node contains aprevious node link, next node link, and value, which contains the actual data. When new data is inserted, a node is inserted and the links of the surrounding nodes are updated accordingly. When one is removed, the same happens – The surrounding nodes are changing their links and the deleted node is garbage collected. This, as well, gives strengths and weaknesses:

  • Fast manipulation As you’d expect, adding and removing new data anywhere in the list is instantanious. Change two links, and you have a new value anywhere you want it.
  • No random access Even though the get(int) is still there, it now just iterates the list until it reaches the index you specified. It has some optimizations in order to do that, but that’s basically it.

There are 3 preferable ways to traverse through a collection and lets see what all are they and when to use them

  1. If you have an iterable and need to traverse unconditionally to all of them, i.e in case where we do not need any indexes or the underlying iterator (i.e. you are only accessing elements, not removing them or modifying the Collection in any way

    for (iterable_type iterable_element : collection)

  2. If you have an iterable but need to conditionally traverse:

    for (Iterator iterator = collection.iterator(); iterator.hasNext();)

  3. If data-structure does not implement iterable:

    for (int i = 0; i < collection.length; i++)

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CompareLists {

private static int compareUnsortedLists(List<String> list1, List<String> list2) {

int counter = 0;

Iterator<String> iter = list2.iterator();
while (iter.hasNext()) {
String element = iter.next();
if (list1.contains(element) && element != null) {
counter++;
}
}
return counter;

}

public static void main(String[] args) {

// declare and populate list lst1
List<String> lst1 = new ArrayList<String>();
lst1.add(“alpha”);
lst1.add(“tau”);
lst1.add(“beta”);
lst1.add(“kappa”);
lst1.add(“gamma”);
lst1.add(“delta”);

// declare and populate list lst2
List<String> lst2 = new ArrayList<String>();
lst2.add(“tim”);
lst2.add(“gamma”);
lst2.add(“beta”);
lst2.add(“peter”);
lst2.add(“kappa”);

System.out.println(“Program to find out the number of matching elements in 2 lists”);
// Call compareUnsortedLists
System.out.println(“The number of common elements is: ” + compareUnsortedLists(lst1, lst2));

}

}

LinkedList & ArrayList are 2 different implementations of the List Interface.

LinkedList allows for constant-time insertions or removals, but only sequential access of elements. In other words, you can walk the list forwards or backwards, but grabbing an element in the middle takes time proportional to the size of the list.

ArrayList, on the other hand, allow random access, so you can grab any element in constant time. But adding or removing from anywhere but the end requires shifting all the latter elements over, either to make an opening or fill the gap. Also, if you add more elements than the capacity of the underlying array, a new array (twice the size) is allocated, and the old array is copied to the new one, so adding to an ArrayList is O(n) in the worst case but constant on average.

The memory usage is also different.

Each element of a LinkedList has more overhead since pointers to the next and previous elements are also stored. ArrayLists don’t have this overhead. However, ArrayLists take up as much memory as is allocated for the capacity, regardless of whether elements have actually been added.

The default initial capacity of an ArrayList is pretty small (10 from Java 1.4 – 6). But since the underlying implementation is an array, the array must be resized if you add a lot of elements. To avoid the high cost of resizing when you know you’re going to add a lot of elements, construct the ArrayList with a higher initial capacity.