0

I have a LinkedHashMap of Item objects. Item has itemId and Color. I want to sort and group my map data, in a way that map is sorted based on insertion sequence, along with colors grouped.

Let me demonstrate with example

Map<String, ItemVO> itemChildMap = new LinkedHashMap<String, ItemVO>();

    ItemVO item1 = new ItemVO("98091", "Red");
    ItemVO item2 = new ItemVO("32456", "Black");
    ItemVO item3 = new ItemVO("12323", "Green");
    ItemVO item4 = new ItemVO("78956", "Red");
    ItemVO item5 = new ItemVO("11231", "Green");
    ItemVO item6 = new ItemVO("10098", "Black");
    ItemVO item7 = new ItemVO("23410", "Red");

    itemChildMap.put("98091", item1);
    itemChildMap.put("32456", item2);
    itemChildMap.put("12323", item3);
    itemChildMap.put("78956", item4);
    itemChildMap.put("11231", item5);
    itemChildMap.put("10098", item6);
    itemChildMap.put("23410", item7);

After sorting and grouping logic, map should be as below:

{98091=ItemVO [itemId='98091', color='Red']
, 78956=ItemVO [itemId='78956', color='Red']
, 23410=ItemVO [itemId='23410', color='Red']
, 32456=ItemVO [itemId='32456', color='Black']
, 10098=ItemVO [itemId='10098', color='Black']
, 12323=ItemVO [itemId='12323', color='Green']
, 11231=ItemVO [itemId='11231', color='Green']
}

Basically, map should contain first all item objects having Red color (which got inserted first), then item objects having Black color, and in the last item objects having Green color.

  • 1
    I once needed the same thing. This helped: [https://stackoverflow.com/a/2581754/7399631](https://stackoverflow.com/a/2581754/7399631) – bkis Jul 17 '17 at 11:18
  • 5
    Possible duplicate of [Sort a Map by values (Java)](https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values-java) – OH GOD SPIDERS Jul 17 '17 at 11:18
  • Do you want to maintain insertion order in the group as well after grouping? – Ashish Lohia Jul 17 '17 at 11:43
  • Hey @mumpitz/ @OH GOD SPIDERS, In that solution is about sorting only, I have checked that. – atulchauhan Jul 17 '17 at 12:10
  • Hi @AshishLohia, It will be good if we can maintain insertion order in the group as well (not mandatory) – atulchauhan Jul 17 '17 at 12:15
  • Hi @atulchauhan, in that case, this is a duplicate question and you can find a lot of answers related to that. Please have a look at those. Still, if you need a solution I can share. – Ashish Lohia Jul 18 '17 at 03:25

2 Answers2

0
public static void main(String[] args){
    Map<String, ItemVO> itemChildMap = new LinkedHashMap<String, ItemVO>();

    ItemVO item1 = new ItemVO("100", "Black");
    ItemVO item2 = new ItemVO("101", "Red");
    ItemVO item3 = new ItemVO("102", "Black");
    ItemVO item4 = new ItemVO("103", "Green");
    ItemVO item5 = new ItemVO("104", "Red");
    ItemVO item6 = new ItemVO("105", "Green");
    ItemVO item7 = new ItemVO("106", "Black");

    itemChildMap.put("100", item1);
    itemChildMap.put("101", item2);
    itemChildMap.put("102", item3);
    itemChildMap.put("103", item4);
    itemChildMap.put("104", item5);
    itemChildMap.put("105", item6);
    itemChildMap.put("106", item7);

    List<Map.Entry<String, ItemVO>> entries = new ArrayList<>(itemChildMap.entrySet());

    Comparator<Map.Entry<String, ItemVO>> comparatorByColor = new Comparator<Map.Entry<String, ItemVO>>() {
        @Override
        public int compare(Map.Entry<String, ItemVO> o1, Map.Entry<String, ItemVO> o2) {
            return o1.getValue().getColor().compareTo(o2.getValue().getColor());
        }
    };

    Comparator<Map.Entry<String, ItemVO>> comparatorById = new Comparator<Map.Entry<String, ItemVO>>() {
        @Override
        public int compare(Map.Entry<String, ItemVO> o1, Map.Entry<String, ItemVO> o2) {
            return o1.getValue().getId().compareTo(o2.getValue().getId());
        }
    };

    System.out.println(itemChildMap);
    Collections.sort(entries, comparatorByColor.thenComparing(comparatorById));
    itemChildMap.clear();
    for (Map.Entry<String, ItemVO> entry : entries) {
        itemChildMap.put(entry.getKey(), entry.getValue());
    }
    System.out.println(itemChildMap);
}

static class ItemVO {
    String id;
    String color;

    public ItemVO(String id, String color) {
        this.id = id;
        this.color = color;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "ItemVO{" +
                "id='" + id + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}
Ashish Lohia
  • 269
  • 1
  • 12
0

Create a LinkedHashMap with key:color and value:List<ItemVO>.

Iterate over itemChildMap and add ItemVO to LinkedHashMap(colorItemListMap).

Then Iterate over colorItemListMap and add all ItemVO to LinkedHashMap(sortedItemMap).

public Map<String, ItemVO> sortItemMap(Map<String, ItemVO> itemChildMap) {
    Map<String, ItemVO> sortedItemMap = new LinkedHashMap<>();
    Map<String, List<ItemVO>> colorItemListMap = new LinkedHashMap<String, List<ItemVO>>();
    for (Map.Entry<String, ItemVO> itemEntry : itemChildMap.entrySet()) {
        String color = itemEntry.getValue().getColor();
        if (!colorItemListMap.containsKey(color)) {
            List<ItemVO> list = new ArrayList<ItemVO>();
            list.add(itemEntry.getValue());
            colorItemListMap.put(color, list);
        } else {
            colorItemListMap.get(color).add(itemEntry.getValue());
        }
    }
    for (Entry<String, List<ItemVO>> entry : colorItemListMap.entrySet()) {
        for (ItemVO itemObj : entry.getValue())
            sortedItemMap.put(itemObj.getItemId(), itemObj);
    }
    System.out.println(sortedItemMap);      
    return sortedItemMap;
}

sortedItemMap contains sorted and grouped ItemVO objects.