-1

I have a hashmap:

Map<Integer, List<String>> dataA = new HashMap<>();

that contains data imported from Excel spreadsheet. HashMap Keys contain row numbers and HashMap Values contain lists of cell values in particular row.

Now I need to sort this by specific column (or multiple columns) from the List.

How to do that?

Michal Jeruzal
  • 89
  • 1
  • 1
  • 6
  • 3
    That would be a bad data structure for it. Move it to an array or a list and sort it. You'll have to think of things like empty rows and what to do with them. – RealSkeptic Apr 02 '19 at 12:54
  • 2
    have you tried looking at something like open csv? http://opencsv.sourceforge.net/ – Katie.Sun Apr 02 '19 at 12:55
  • This question: [Sort a Map by value](https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values), should maybe give you an idea – Lino Apr 02 '19 at 12:57
  • Could you provide more detail on the work you have already done or how your problem with your current solution? This is vague and comes across as a request to do your homework for you. – wolfcall Apr 02 '19 at 13:01
  • 1
    what you have tried so far?? Google your question, i am sure there are plenty over SO like yours. – Vishwa Ratna Apr 02 '19 at 13:01

4 Answers4

2

A Map<Integer, ____> when dealing with contiguous keys is almost always the wrong choice of data structure.

0 -> Foo
1 -> Bar
2 -> Baz

Do you recognise what this is? It's literally just a list. Use a List<List<String>> and it'll make your life easier.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • 1
    OP did not state that the row numbers are contiguous or that they start at 0. – Balz Guenat Apr 02 '19 at 13:09
  • @BalzGuenat They are rows of a spreadsheet so they are kind of bound to be contiguous. You can have an empty `List` if the row is empty. – Michael Apr 02 '19 at 13:10
  • 1
    @BalzGuenat It doesn't matter if they start at zero or not. Store them zero-indexed and, if you need to, then store an offset as an integer separately and add that to the index when you need to refer to the row. – Michael Apr 02 '19 at 13:11
  • 1
    Only if you insert *all* rows of the spreadsheet. Could be that they are filtered with the original row number preserved. – Balz Guenat Apr 02 '19 at 13:12
  • Or just store the original row number without messing with offsets, yes. – Balz Guenat Apr 02 '19 at 13:13
  • @BalzGuenat It's possible, but if your point is that I'm making assumptions, well now so are you, because it was never specified that the rows were filtered. – Michael Apr 02 '19 at 13:13
  • 1
    @Michael Thank you. It works perfectly fine and indeed is easier to maintain. – Michal Jeruzal Apr 02 '19 at 14:01
0

To sort hashmap contents by value part, use comparator and compare value part of hashmap instead of key part.

Following code can be used in compare method of Comparator which can be supplied to TreeMap constructor.

public int compare(Map.Entry<Integer, List<String>> o1,  
                               Map.Entry<Integer, List<String>> o2) 
            { 
                return (o1.getValue().get(0)).compareTo(o2.getValue().get(0)); 
            } 

In above code replace 0 with any of the column index.

Abhijeet
  • 4,069
  • 1
  • 22
  • 38
0

If you want a Map to be ordered, the thing to use is a TreeMap.

Then you need a class for your ordering keys, e.g. MySortKey implements Comparable<...>.

Then you need a method somewhere that can produce the appropriate MySortKey object from each List<String> that is [currently] a value in your Map.

Then you populate the TreeMap using .put(mySortKey, list) where these two variables are the MySortKey and List<String> objects.

Erwin Smout
  • 18,113
  • 4
  • 33
  • 52
0

Get the value set and sort it by a custom Comparator:

Comparator<Map.Entry<Integer, List<String>>> comp = 
  Comparator.comparing((Map.Entry<Integer, List<String>> e) -> e.getValue().get(firstColumnIndex))
            .thenComparing(e -> e.getValue().get(secondColumnIndex));
List<Map.Entry<Integer, List<String>>> sorted =
  map.entrySet().stream().sorted(comp).collect(Collectors.toList());
Balz Guenat
  • 1,552
  • 2
  • 15
  • 35
  • Didn't you imply that working with maps was easier? :D – Michael Apr 02 '19 at 13:19
  • Not easier but necessary if the keys are not 0-indexed and contiguous. This solution will work with any input map, as it makes no assumptions about the keys. (It does make an assumption about the length of the value lists, though.) – Balz Guenat Apr 02 '19 at 13:26