Saturday, November 15, 2014

Sort a Map by value in Java

In Java, you simply use a TreeMap to have a map sorted by key.

But quite often, we need to sort a map by its value.

The method below will help you sort a map by its value. Simply use it in your code.

private static Map<String, String> sortMapByValue(Map<String, String> unsortMap) {
 // Convert Map to List
 List<Map.Entry<String, String>> list = 
  new LinkedList<Map.Entry<String, String>>(unsortMap.entrySet());

 // Sort list with comparator, to compare the Map values
 Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
  public int compare(Map.Entry<String, String> o1,
          Map.Entry<String, String> o2) {
   return (o1.getValue()).compareTo(o2.getValue());
  }
 });

 // Convert sorted map back to a Map
 Map<String, String> sortedMap = new LinkedHashMap<String, String>();
 for (Iterator<Map.Entry<String, String>> it = list.iterator(); it.hasNext();) {
  Map.Entry<String, String> entry = it.next();
  sortedMap.put(entry.getKey(), entry.getValue());
 }
 return sortedMap;
}


Cheers!

Removing elements while iterating a Set in Java

Use an Iterator when removing an item from a Set Collection while iterating it so that it will not cause undefined behavior or the 'java.util.ConcurrentModificationException' exception.

To remove elements from a Set while iterating, you may use Iterator as shown below:

//set a reference to the set 
Set<Person> personSet = .....

//remove an element while iterating the set
Iterator<Person> iter = personSet.iterator();
while (iter.hasNext()) {
    Person person = iter.next();
    if (..condition here..) {
        // Remove the current element from the iterator and the set.
        iter.remove();
    }
}

You may also use a for-loop as shown below:

//set a reference to the set 
Set<Person> personSet = .....

//remove an element while iterating the set
for (Iterator<Person> iter = personSet.iterator(); iter.hasNext();) {
    Person person = iter.next();
    if (..condition here..) {
        // Remove the current element from the iterator and the set.
        iter.remove();
    }
}

Note that Iterator.remove is the only safe way to modify a collection during iteration. The behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

Collection API
Set API

Removing elements while iterating a Map in Java

Use an Iterator when removing an item from a Map Collection while iterating it so that it will not cause undefined behavior or the 'java.util.ConcurrentModificationException' exception.

To remove elements from a Map while iterating, you should use Iterator as shown below:

//set a reference to the map
Map<String,Person> groupPersonMap = .....

Iterator<Map.Entry<String,Person>> iter = groupPersonMap.entrySet().iterator();
while (iter.hasNext()) {
   Map.Entry<String,PersonObj> entry = iter.next();
   String groupId = entry.getKey();
   Person person = entry.getValue();
   if ("name filter here".equals(person.getName())) {
      // Remove the current element from the iterator and the map.
      iter.remove();
   }
}

Note that Iterator.remove is the only safe way to modify a collection during iteration. The behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

Collection API
Map API

Removing elements while iterating a List in Java

Use an Iterator when removing an item from a List Collection while iterating it so that it will not cause undefined behavior or the 'java.util.ConcurrentModificationException' exception.

To remove elements from a List while iterating, you should use Iterator as shown below:

//set a reference to the list 
List<String> nameList = .....

//remove an element while iterating the list
Iterator<String> iter = nameList.iterator();
while (iter.hasNext()) {
    String name = iter.next();
    if (..condition here..) {
        // Remove the current element from the iterator and the list.
        iter.remove();
    }
}


You may also use a for-loop as shown below:

//set a reference to the list 
List<String> nameList = .....

//remove an element while iterating the list
for (Iterator<String> iter = nameList.iterator(); iter.hasNext();) {
    String name = iter.next();
    if (..condition here..) {
        // Remove the current element from the iterator and the list.
        iter.remove();
    }
}


You may also use a ListIterator by using the List's listIterator() method.

//set a reference to the list 
List<String> nameList = .....

//remove an element while iterating the list
Iterator<String> iter = nameList.listIterator();
while (iter.hasNext()) {
    String name = iter.next();
    if (..condition here..) {
        // Remove the current element from the iterator and the list.
        iter.remove();
    }
}


Note that Iterator.remove()  and ListIterator.remove() is the only safe way to modify a collection during iteration. The behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

Collection
Collection API
List API



Saturday, November 1, 2014

Check for duplicates in a List

A List typically allow duplicate elements. List is an ordered collection interface.

If you want to prevent duplicates, you would typically want to use a Set. If maintaining order is needed, use LinkedHashSet.

However, there are instances where you want to use a List and prevent duplicate elements when adding to the list.

You can check for duplicates in the List by using the HashSet(list) technique outlined below.


You should first override equals() and hashcode() methods in your class.

public class IncentiveVB implements Serializable  {

 private static final long serialVersionUID = 1L;
 

 private String incentiveId;
 
 private String incentiveName;
 
 private String incentiveCode;
 
 private String inputType; 
 
 /*
  * getters and setters here
  */
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result
    + ((incentiveId == null) ? 0 : incentiveId.hashCode());
  result = prime * result
    + ((incentiveName == null) ? 0 : incentiveName.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  IncentiveVB other = (IncentiveVB) obj;
  if (incentiveId == null) {
   if (other.incentiveId != null)
    return false;
  } else if (!incentiveId.equals(other.incentiveId))
   return false;
  if (incentiveName == null) {
   if (other.incentiveName != null)
    return false;
  } else if (!incentiveName.equals(other.incentiveName))
   return false;
  return true;
 } 
}


Here's a few ways you can override the equals() and hashCode() methods

Then, in your code check for duplicates in the list before actually adding an object into the list as shown below.

List<IncentiveVB> incentiveVBList = ....;
 
for (condition...) {

 /*
  * code to create 'incentiveVB' object here
  */

 //check for duplicates of this IncentiveVB in the list before adding to the list
 //by testing a copy of your List against a HashSet
 List<IncentiveVB> list = new ArrayList<IncentiveVB>(incentiveVBList);
 list.add(incentiveVB);
 Set<IncentiveVB> set = new HashSet<IncentiveVB>(list);
 if(set.size() < list.size()){
  //there are duplicates of this IncentiveVB in the list. don't add.
  continue;
 }
 incentiveVBList.add(incentiveVB);
}