Immutable Empty , Sub and Unmodifiable Collection


Removing matching items from Lists using Iterator

Above I noticed an example to remove items from a List within a Loop and I thought of another example that may come in handy this time using the Iterator interface.

This is a demonstration of a trick that might come in handy when dealing with duplicate items in lists that you want to get rid of.

Note : This is only adding on to the Removing items from a List within a loop example:

So let's define our lists as usual

String[] names = {"James","Smith","Sonny","Huckle","Berry","Finn","Allan"};
List<String> nameList = new ArrayList<>();
 
//Create a List from an Array
nameList.addAll(Arrays.asList(names));
 
String[] removeNames = {"Sonny","Huckle","Berry"};
List<String> removeNameList = new ArrayList<>();
 
//Create a List from an Array
removeNameList.addAll(Arrays.asList(removeNames));

The following method takes in two Collection objects and performs the magic of removing the elements in our removeNameList that match with elements in nameList.

private static void removeNames(Collection<String> collection1, Collection<String> collection2) {
 //get Iterator.
 Iterator<String> iterator = collection1.iterator();
 
 //Loop while collection has items
 while(iterator.hasNext()){
 if (collection2.contains(iterator.next()))
 iterator.remove(); //remove the current Name or Item
 }
}

Calling the method and passing in the nameList and the removeNameListas follows

removeNames(nameList,removeNameList);

Will produce the following output:

  • Array List before removing names: James Smith Sonny Huckle Berry Finn Allan
  • Array List after removing names: James Smith Finn Allan

A simple neat use for Collections that may come in handy to remove repeating elements within lists.


Join lists

Following ways can be used for joining lists without modifying source list(s).

First approach. Has more lines but easy to understand

List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);

Second approach. Has one less line but less readable.

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

Third approach. Requires third party Apache commons-collections library.

ListUtils.union(listOne,listTwo);

Using Streams the same can be achieved by

//Version ≥ Java SE 8
 
List<String> newList = Stream.concat(listOne.stream(),
listTwo.stream()).collect(Collectors.toList())

Pitfall: concurrent modification exceptions

This exception occurs when a collection is modified while iterating over it using methods other than those provided by the iterator object. For example, we have a list of hats and we want to remove all those that have ear flaps:

List<IHat> hats = new ArrayList<>();
hats.add(new Ushanka()); // that one has ear flaps
hats.add(new Fedora());
hats.add(new Sombrero());
for (IHat hat : hats) {
    if (hat.hasEarFlaps()) {
        hats.remove(hat);
    }
}
 

If we run this code, ConcurrentModificationException will be raised since the code modifies the collection while iterating it. The same exception may occur if one of the multiple threads working with the same list is trying to modify the collection while others iterate over it. Concurrent modification of collections in multiple threads is a natural thing, but should be treated with usual tools from the concurrent programming toolbox such as synchronization locks, special collections adopted for concurrent modification, modifying the cloned collection from initial etc.

Basic Programs