简体   繁体   中英

Sorting HashMap using its list values in Android (Map<Integer, List<Item>>)

I have created a HashMap using json response which I want to use its data group by month.

My json

[
   {
      "type":"CLAIMS PAID",
      "category":"01. Less than 0",
      "month":11,
      "year":2020,
      "count":173
   },
   {
      "type":"CLAIMS PAID",
      "category":"02. 1-5",
      "month":11,
      "year":2020,
      "count":445
   },
   {
      "type":"CLAIMS PAID",
      "category":"03. 6-10",
      "month":11,
      "year":2020,
      "count":362
   },
   {
      "type":"CLAIMS PAID",
      "category":"04. 11-15",
      "month":11,
      "year":2020,
      "count":241
   },
   {
      "type":"CLAIMS PAID",
      "category":"05. 16-20",
      "month":11,
      "year":2020,
      "count":130
   },
   {
      "type":"CLAIMS PAID",
      "category":"06. 21-25",
      "month":11,
      "year":2020,
      "count":115
   },
   {
      "type":"CLAIMS PAID",
      "category":"07. 26-30",
      "month":11,
      "year":2020,
      "count":66
   },
   {
      "type":"CLAIMS PAID",
      "category":"08. 31-35",
      "month":11,
      "year":2020,
      "count":32
   },
   {
      "type":"CLAIMS PAID",
      "category":"09. More than 35",
      "month":11,
      "year":2020,
      "count":251
   },
   {
      "type":"CLAIMS PAID",
      "category":"01. Less than 0",
      "month":12,
      "year":2020,
      "count":257
   },
   {
      "type":"CLAIMS PAID",
      "category":"02. 1-5",
      "month":12,
      "year":2020,
      "count":726
   },
   {
      "type":"CLAIMS PAID",
      "category":"03. 6-10",
      "month":12,
      "year":2020,
      "count":722
   },
   {
      "type":"CLAIMS PAID",
      "category":"04. 11-15",
      "month":12,
      "year":2020,
      "count":378
   },
   {
      "type":"CLAIMS PAID",
      "category":"05. 16-20",
      "month":12,
      "year":2020,
      "count":207
   },
   {
      "type":"CLAIMS PAID",
      "category":"06. 21-25",
      "month":12,
      "year":2020,
      "count":151
   },
   {
      "type":"CLAIMS PAID",
      "category":"07. 26-30",
      "month":12,
      "year":2020,
      "count":94
   },
   {
      "type":"CLAIMS PAID",
      "category":"08. 31-35",
      "month":12,
      "year":2020,
      "count":56
   },
   {
      "type":"CLAIMS PAID",
      "category":"09. More than 35",
      "month":12,
      "year":2020,
      "count":351
   },
   {
      "type":"CLAIMS PAID",
      "category":"01. Less than 0",
      "month":1,
      "year":2021,
      "count":254
   },
   {
      "type":"CLAIMS PAID",
      "category":"02. 1-5",
      "month":1,
      "year":2021,
      "count":693
   },
   {
      "type":"CLAIMS PAID",
      "category":"03. 6-10",
      "month":1,
      "year":2021,
      "count":538
   },
   {
      "type":"CLAIMS PAID",
      "category":"04. 11-15",
      "month":1,
      "year":2021,
      "count":287
   },
   {
      "type":"CLAIMS PAID",
      "category":"05. 16-20",
      "month":1,
      "year":2021,
      "count":194
   },
   {
      "type":"CLAIMS PAID",
      "category":"06. 21-25",
      "month":1,
      "year":2021,
      "count":144
   },
   {
      "type":"CLAIMS PAID",
      "category":"07. 26-30",
      "month":1,
      "year":2021,
      "count":110
   },
   {
      "type":"CLAIMS PAID",
      "category":"08. 31-35",
      "month":1,
      "year":2021,
      "count":73
   },
   {
      "type":"CLAIMS PAID",
      "category":"09. More than 35",
      "month":1,
      "year":2021,
      "count":372
   },
   {
      "type":"CLAIMS PAID",
      "category":"01. Less than 0",
      "month":2,
      "year":2021,
      "count":225
   },
   {
      "type":"CLAIMS PAID",
      "category":"02. 1-5",
      "month":2,
      "year":2021,
      "count":960
   },
   {
      "type":"CLAIMS PAID",
      "category":"03. 6-10",
      "month":2,
      "year":2021,
      "count":733
   },
   {
      "type":"CLAIMS PAID",
      "category":"04. 11-15",
      "month":2,
      "year":2021,
      "count":360
   },
   {
      "type":"CLAIMS PAID",
      "category":"05. 16-20",
      "month":2,
      "year":2021,
      "count":200
   },
   {
      "type":"CLAIMS PAID",
      "category":"06. 21-25",
      "month":2,
      "year":2021,
      "count":145
   },
   {
      "type":"CLAIMS PAID",
      "category":"07. 26-30",
      "month":2,
      "year":2021,
      "count":107
   },
   {
      "type":"CLAIMS PAID",
      "category":"08. 31-35",
      "month":2,
      "year":2021,
      "count":51
   },
   {
      "type":"CLAIMS PAID",
      "category":"09. More than 35",
      "month":2,
      "year":2021,
      "count":271
   }
]

Object class

public class Item{

    private String type;
    private String category;
    private int month;
    private int year;
    private String monthName;
    private String count;

}


                JSONArray resArray = new JSONArray(jsonresponse);
                for (int i = 0; i < resArray.length(); i++) {

                    JSONObject jo = resArray.getJSONObject(i);
                    Item ariData = new Item();
                    ariData.setType(jo.getString("type"));
                    ariData.setCategory(jo.getString("category"));
                    ariData.setYear(jo.getInt("year"));
                    ariData.setMonth(jo.getInt("month"));
                    ariData.setMonthName(getMonthFullName(jo.getInt("month")));
                    ariData.setCount(jo.getString("count"));
                    ariList.add(ariData);

                }

I want to display same month's data in a RecyclerView so I have grouped by this json its Month for display in the RecyclerView. So I put it into a HashMap using..

Map<Integer, List<Item>> objectsPer = ariList.stream()
                                .collect(Collectors.groupingBy(Item::getMonth));

Problem is, If there is two years' data for example 2020-12 and 2021-01 then 2020-12 month's data display after 2021-01 data. I know this is happening because of the group by using month. I want to sort this HashMap using year also.

Edit

public class Item{

private String type;
private String category;
private String count;
private int total;
private YearMonth yearMonth;

}

  JSONArray resArray = new JSONArray(response);
                        for (int i = 0; i < resArray.length(); i++) {

                            JSONObject jo = resArray.getJSONObject(i);
                            Item ariData = new Item();
                            ariData.setType(jo.getString("type"));
                            ariData.setCategory(jo.getString("category"));
                            ariData.setCount(jo.getString("count"));
                            YearMonth yMonth = YearMonth.of(jo.getInt("year"), jo.getInt("month"));
                            ariData.setYearMonth(yMonth);
                            ariList.add(ariData);

                        }

                        Map<YearMonth, List<Item>> objectsPer = ariList.stream()
                                .collect(Collectors.groupingBy(Item::getYearMonth));

Here I put date range in 2021-03 to 2021-06

see the debug I get for this date range after group by using year month

在此处输入图像描述

Here I put date range in 2020-11 to 2021-06

在此处输入图像描述

YearMonth

As commented by deHaar, you should be using the java.time.YearMonth class rather than your separate int fields for year and for month. And no need for storing month name as that can be determined dynamically by calling YearMonth#getMonth and Month#getDisplayName .

Redefine your class, with less fields: String type, String category, YearMonth yearMonth, int count.

(Shouldn't count be an integer number rather than String ?)

By the way, in Java 16+, we can define a class more briefly as a record if its main purpose is to communicate data transparently and immutably. Simply declare the type and name of each member field. The compiler implicitly creates the constructor, getters, equals & hashCode , and toString . You can even declare a record locally.

public record Item ( String type, String category, YearMonth yearMonth,  int count ) {}

You could just as well define a conventional class in the context of this Answer. A record is simply more convenient.

By the way, type and category should probably be defined each in their own enum rather than as String . But that's a whole other matter.

NavigableMap , NavigableSet

Collect your Item objects in a map. Use a navigable map and navigable set to keep sorted by YearMonth .

Perhaps use TreeMap and TreeSet as your choice of implementations. When constructing the TreeSet objects, pass a Comparator to organize the sorting.

NavigableMap< YearMonth , NavigableSet< Item > > = …

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM