Grouping Java objects using object’s properties/fields

June 12th, 2010 | Posted by admin in java | Software Development

I 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.

One Response

  • Ram Kakani says:

    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



Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>