Grouping Java objects using object’s properties/fields
June 12th, 2010 | Posted by in java | Software DevelopmentI recently had to build a HTML select list with items grouped by category .
The list had to be populated using ajax as using simple jsp tag wasn’t enough as I needed other
properties besides simple key/ value and group for validation and displaying description of the selected item using javascript .
Since grouping objects can be quite quite handy for displaying grouped data in forms and in reports I ended up creating a utility method in java which takes a List of objects and a field name to group the objects by ,
and returns a map with keys as the values of the field name and values a a list of objects under this group.
Here’s the method .
/**
* Groups objects using field name provided
* @param list the list of objects to group
* @param field the field to group the objects by
* @return new Map containing list of objects.
* The Map's key is the property specified in criteria object
*/
public static <V> Map<String,List<V>> group(List<V> list, String field) {
//used for indexing to avoid too much looping
HashMap<String,K> index= new HashMap<String,K>();
// the container for grouped data. K is the data type for the field's value.
HashMap<K,List<V>> groupedData= new HashMap<K, List<V>>();
// the method to invoke to get the value of the 'field' prop from objects
Method m=null;
try {
V obj=list.get(0);
// Used a handy Util Class's method for getting the getter method for 'field'
m = ClassUtil.getMethod(obj.getClass(), "get"+StringUtil.getFirstUpper(field));
} catch (NoSuchMethodException ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
//iterate through the list of objects passed as parameter
for (V object : list) {
//the 'field' value of object
K columnVal=null;
try {
columnVal = (K) m.invoke(object, null);
// group of objects under columnVal group
List<V> group=groupedData.get(index.get(columnVal.toString()));
if(group==null){
group= new ArrayList<V>();
groupedData.put(columnVal, group);
index.put(columnVal.toString(), columnVal);
}
//add the object to the group
group.add(object);
} catch (Exception ex) {
Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
}
}
return groupedData;
}
here’s a simple test:
List<Command> commands= new ArrayList();
//create objects to populate a list;
Command comm= new DeviceCommand();
comm.setCommand("CONTROL comm1");
comm.setCommandType(CommandType.CONTROL);
comm.setName(" CONTROL command 1");
commands.add(comm);
Command comm2= new DeviceCommand();
comm2.setCommand("comm2");
comm2.setCommandType(CommandType.CONTROL);
comm2.setName(" CONTROL command 2");
commands.add(comm2);
Command comm3= new DeviceCommand();
comm3.setCommand("INFORMATION comm1");
comm3.setCommandType(CommandType.INFORMATION);
comm3.setName("INFORMATION command 1");
commands.add(comm3);
Command comm5= new DeviceCommand();
comm5.setCommand("SETTING comm1");
comm5.setCommandType(CommandType.SETTING);
comm5.setName("SETTING command 1");
commands.add(comm5);
Command comm6= new DeviceCommand();
comm6.setCommand("SETTING comm2");
comm6.setCommandType(CommandType.SETTING);
comm6.setName("SETTING command 2");
commands.add(comm6);
Command comm8= new DeviceCommand();
comm8.setCommand("OTHER comm1");
comm8.setCommandType(CommandType.OTHER);
comm8.setName("OTHER command 1");
commands.add(comm8);
Command comm4= new DeviceCommand();
comm4.setCommand("CONTROL comm4");
comm4.setCommandType(CommandType.CONTROL);
comm4.setName("CONTROL command 4");
commands.add(comm4);
Command comm7= new DeviceCommand();
comm7.setCommand("SETTING comm3");
comm7.setCommandType(CommandType.SETTING);
comm7.setName("SETTING command 3");
commands.add(comm7);
Command comm9= new DeviceCommand();
comm9.setCommand("OTHER comm2");
comm9.setCommandType(CommandType.OTHER);
comm9.setName("OTHER command 2");
commands.add(comm9);
Command comm10= new DeviceCommand();
comm10.setCommand("OTHER comm3");
comm10.setCommandType(CommandType.OTHER);
comm10.setName("OTHER command 3");
commands.add(comm10);
//convert list of Command objects into a map with commandTpe as key and list of Commands within
// that group as map value.
Map<String,List<Command>> grouped=ListUtil.group(commands, "commandType");
//print out the grouped map data.
System.out.println(grouped.toString());
And the string representation of the grouped data :
{OTHER=[OTHER command 1, OTHER command 2, OTHER command 3], SETTING=[SETTING command 1, SETTING command 2, SETTING command 3], CONTROL=[ CONTROL command 1, CONTROL command 2, CONTROL command 4], INFORMATION=[INFORMATION command 1]}
You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

Hi Anzaan, I have a very similar situation regarding grouping a Array List of View Objects based on the View Object’s attribute. Could you please send the above code along with ClassUtil and ListUtil to my email address
rvkakani@yahoo.com
your help is much appreciated.
Thanks
Ram Kakani