1

This code is written to sort the hashmap monthwise but i am not able to understand completely. Can anyone explain this. Also i want to know if i am accessing hashmap correctly in for loop. monthAnalysis is the name of hashmap and month is key. Sorry i forgot to mention that i know that it adds the data to table creating rows dynamically. my problem is in first 4 lines of code.

public void addData1(TableLayout tableLayout, HashMap<String, MonthAnalysis> monthAnalysis) {

    String[] sortedMonthList = (String[]) monthAnalysis.keySet().toArray();
    Arrays.sort(sortedMonthList);

    for (String month : sortedMonthList) {
        /* Create a TableRow dynamically */
        TableRow tr = new TableRow(this);
        tr.setLayoutParams(new TableLayout.LayoutParams(
                TableLayout.LayoutParams.MATCH_PARENT,
                TableLayout.LayoutParams.WRAP_CONTENT));
        addRowItem(tr, getMonth(month), 1.3f, Typeface.DEFAULT, Color.parseColor("#000000"), Gravity.LEFT);
        addRowItem(tr, Long.toString(monthAnalysis.get(month).credit), 0.9f, Typeface.DEFAULT, Color.parseColor("#000000"), Gravity.RIGHT);
        addRowItem(tr, Long.toString(monthAnalysis.get(month).debit), 1f, Typeface.DEFAULT, Color.parseColor("#000000"), Gravity.RIGHT);
        //addRowItem(tr, convertDate(Long.parseLong(transaction.date)), 1.5f, Typeface.DEFAULT, Color.parseColor("#000000"), Gravity.RIGHT);

        tableLayout.addView(tr, new TableRow.LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT));
    }
}
Naresh Mobarsa
  • 101
  • 1
  • 9

1 Answers1

5
String[] sortedMonthList = (String[]) monthAnalysis.keySet().toArray();

That map uses String objects representing Month names as KEYS. The above retrieves those keys (as Set); and turns that Set into an array of Strings.

Arrays.sort(sortedMonthList);

That array is now sorted alphabetically.

for (String month : sortedMonthList) {

and then iterated in that new sorted order. That is all there is to this.

But of course, there are subtle details such as: depending on how those month names actually look like, the above simply doesn't make to much sense. You see, if those month names would be "January", "Februrary", ... would you really expect that "sorting by month" results in an order like "April", "Februrary", "January", ... and so on?!

In other words: this code looks pretty suspicious to me; but it really depends on the content of the incoming Map to determine if this code makes "some sense"; or is "completely bogus".

You have to understand: strings are just sequences of characters. Any meta information, such as "January" should be in front of "February" is lost when you look at these values from that perspective. As one of the comments suggest, a better solution is to use an Enum instead of a String; as Enums can be written to follow a specific order (see here for how to do that).

And of course, if you want to continue with "raw" strings, instead of enums, you can also do that. The only pre-condition there: you have to really understand how those strings look like. You can sort using a custom Comparator. And for sure; when you know that you have exactly 12 strings that could be sorted, and you know how they would look like; then you could write a comparator that understands that compare("Jan", "Feb") should result in "Jan" being "smaller" than "Feb". This is possible, but seriously going in the wrong direction.

You don't write programs to "somehow" get to the expected output. You do not make unnecessary detours; you don't work around symptoms; you look at the root cause of the problem, and address that!

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thanks. So it doesn't sort the month in correct order, Like (Jan, Feb, Mar...Dec) ? – Naresh Mobarsa May 11 '17 at 08:54
  • I agree, if you cannot have the key as `Date`s, it would be better to at least declare an orderable enum Month (with the proper formatting) to sort keys on. There's also a better way to implement the for loop (`monthAnalysis.entrySet().stream().sorted(...).forEach(...)`) but that's another matter. – Jeremy Grand May 11 '17 at 08:57
  • @NareshMobarsa No it doesn't, because simple Strings do not know the order of every month in every possible language, you cannot expect the Array to sort them as you want. – Jeremy Grand May 11 '17 at 08:59
  • @NareshMobarsa Exactly. Two strings "jan" "feb" can only be sorted alphabetically. If you want to express more than just-characters; you need "more" than strings. See my updated answer; new paragraph in the end addressing this. – GhostCat May 11 '17 at 09:10
  • ok i will try that. Is there any method to sort it in the order i saved it into the the hashmap without using enum? Like if the first key i saved to hashmap were March then i want it to show March in my first row when populating data into table? – Naresh Mobarsa May 11 '17 at 09:38
  • @NareshMobarsa As GhostCat stated above, maybe it's better to solve this problem by better design instead of exploring in the wrong direction. As for your latest comment, HashMap is a disordered data structure, maybe LinkedHashMap is a better choice, and you can get item in the order you put into it with for loop. It's always recommend to choose right data structure that fits your problem. – Longer May 12 '17 at 02:38