3

I need your assiatance please:

I have a map :

Map<String, Object[]> data = new HashMap<String, Object[]>();

The Object[] array is built out of triples: [String, String, Integer]

Later on, I am going to read the object[] array values, but I should print them sorted according to the integer value.

How can I do this in the best way?

Thank you!

dushkin
  • 1,939
  • 3
  • 37
  • 82
  • 2
    Why not create a class with 2 String, and an Integer field, rather than this bizarre Object array? Are you going to sort Object[]'s according to the Integer in them? Map is not useful at all for sorting, you can get the valueSet of the map which will be a `Set` and from this set, you can sort according to the Integer value. – buræquete Feb 17 '16 at 11:21
  • @bureaquete Well, I was just using an example I have found of using APACHE POI API. There they used a map of a row number and an array of its values, whihch may be of different types. – dushkin Feb 17 '16 at 11:28
  • What do you mean by 'best'? – Alex - GlassEditor.com Feb 17 '16 at 11:29
  • @Alex The most effective, most elegant. But any solution will be blessed :-) – dushkin Feb 17 '16 at 11:30
  • Why do you do `new HashMap()` ? Don't you use Java 7+? With streams, it will be much easier to do the sorting. Only if it were not a Object[] but a complex object. – buræquete Feb 17 '16 at 11:36
  • @bureaquete As I said - I am basing my code to the POI API, and they used this method of storing the row data. And I didn't want to spend time on changing it and taking the risk I will fail. So I'd currently like to continue with their code. This is regardless to the fact that you are right :-) – dushkin Feb 17 '16 at 11:50
  • @dushkin Sorry, I just cannot stop thinking of refactoring all that code!! :) – buræquete Feb 17 '16 at 11:51

3 Answers3

2

First you have to extract the values from the map. Then you can use a sort method implementation from native java, with your custom comparator.

Map<String, Object[]> data = new HashMap<String, Object[]>();
List<Object[]> values = new ArrayList<Object[]>();
values.addAll(data.values());
Collections.sort(values, new Comparator<Object[]>()
{
    @Override
    public int compare(Object[] o1, Object[] o2)
    {
        // TODO implement me
        // o1 less than o2 ? return -1
        // o1 greater than o2 ? return 1
        // o1 equals o2 ? return 0
    }
});

In this example you only need to implement the compare method. From the docs:

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

You can also take a look at: Sort ArrayList of custom Objects by property

Community
  • 1
  • 1
kai
  • 6,702
  • 22
  • 38
  • Yep thats exactly what should be done. I wanted to answere the same but I had an appointment . Notice, that his Object can also implement Comparable wich would render the instantiation of a new ArrayList unnessasary – Tom Wellbrock Feb 17 '16 at 11:31
  • 1
    We have Java 8 so the diamond shortcut for a generic type can be used. Plus, we have streams. –  Feb 17 '16 at 11:35
  • the diamond shortcut is available since Java 7. – Tom Wellbrock Feb 17 '16 at 11:37
2

One way is with a stream:

data.values().stream()
    .sorted(Comparator.comparing(a -> (Integer)a[2]))
    .forEachOrdered(a -> System.out.println(Arrays.toString(a)));
Alex - GlassEditor.com
  • 14,957
  • 5
  • 49
  • 49
2

Use Java 8 to sort the values.

final Map<String, Object[]> data = new HashMap<>();
data.put("foo", new Object[]{"A", "B", 1});
data.put("bar", new Object[]{"C", "D", 2});
data.put("baz", new Object[]{"E", "F", 3});

final Comparator<Object[]> comparator = (oa1, oa2) ->
   ((Integer) oa1[2]).compareTo((Integer) oa2[2]);

List<Object[]> sorted = 
    data.values().stream().sorted(comparator).collect(Collectors.toList());