1

I'm trying to sort a map by value. The data structure is as follows:

Map<String, ArrayList<Object>>

The ArrayList contains a set of properties for a set of objects whose name corresponds to the string key value in the map.

The idea is that I want to sort these objects by property. So, let's say that transparency was a property of these objects, and transparency is stored in ArrayList.get(3) for all objects.

How would I be able to sort it in a way such that:

I'm able to output:

Transparency     Object Name
   Value            Name 1
   Value            Name 2
   Value            Name 3 
   Value            Name 4

I've tried a few different sorts, and nothing seems to be working. Any ideas?

Edit: More information.

The objects inside the arrayList are all either Double type or String type, and I am defining the comparison between the two values through their default comparison. Essentially, I've organized the data like this:

The name of the object whose properties are contained in a list is the key for the map. The value given by the key is the list of properties for that object. I want to compare property(i), where i is user input, of Object A with property(i) of Object B, and then output them using System.out.print() or printf()

wadda_wadda
  • 966
  • 1
  • 8
  • 29
  • http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html – Cruncher Sep 18 '13 at 19:55
  • 3
    Also, what do you mean "sorting a Map". Maps are orderless – Cruncher Sep 18 '13 at 19:57
  • 1
    http://stackoverflow.com/a/2581754/869736 – Louis Wasserman Sep 18 '13 at 19:57
  • 1
    Your question is unclear. How do you define the comparison between two value arraylist objects. Please provide a more explicit example of the contents of your map. i.e. `Key=xxx,Value={a,b,c}; Key=yyy,Value={x,y,z}; etc...` and then show how you want the results arranged, and the rules for the comparison. – Jim Garrison Sep 18 '13 at 20:10
  • @JimGarrison I've included more information. – wadda_wadda Sep 18 '13 at 20:21
  • @Cruncher You may simulate a sorted map with `LinkedHashMap`. – Georgian Sep 18 '13 at 20:21
  • @GGrec Given an Object in which the only information you're given about it is that it's a `Map`, you cannot infer any order. – Cruncher Sep 18 '13 at 20:23
  • @Cruncher would you suggest that instead of using a Map where the values inside are arraylist that I use a nested arraylist (ArrayList>)? – wadda_wadda Sep 18 '13 at 20:27
  • @user130173 If order is important, maybe. Maps are for being able to take an object, and map it into another. Maps are simply not designed for ordering. – Cruncher Sep 18 '13 at 20:28
  • @Cruncher Alright. I'll try restructuring. Thanks for your input – I'm still learning! :D – wadda_wadda Sep 18 '13 at 20:29
  • You're still going to need to define a comparator. Reading the link in my first comment should help. – Cruncher Sep 18 '13 at 20:31

1 Answers1

1

How about implementing the Comparator interface using a class which accepts an index value a a config parameter to use when the compare method is invoked? And sort on the map.entrySet() ?

e.g :

   import java.util.*;

public class AClass {

    static Map<String, List<Object>> myMap = new HashMap<>();
    static final int ALPHA_ZULU = 0;
    static final int SOME_DOUBLE = 1;

    public static void main(String[] args) {

        List<Object> l1 = new ArrayList<>();
        l1.add("CHARLIE");
        l1.add(new Double(1));
        List<Object> l2 = new ArrayList<>();
        l2.add("ZULU");
        l2.add(new Double(9));
        List<Object> l3 = new ArrayList<>();
        l3.add("ALPHA");
        l3.add(new Double(12));
        List<Object> l4 = new ArrayList<>();
        l4.add("XRAY");
        l4.add(new Double(4));

        myMap.put("one", l1);
        myMap.put("two", l2);
        myMap.put("three", l3);
        myMap.put("four", l4);


        List<Map.Entry<String, List<Object>>> meList = new ArrayList<>(myMap.entrySet());
        Collections.sort(meList, new MyComaprator(ALPHA_ZULU));

        for(Map.Entry me : meList) {
            System.out.println(me.getKey() + " = " + me.getValue());
        }

    }






}


class MyComaprator implements Comparator<Map.Entry<String,List<Object>>> {

    final int compareIndex;

    public MyComaprator(int compareIndex) {
        this.compareIndex = compareIndex;
    }

    @Override
    public int compare(Map.Entry<String, List<Object>> me1, Map.Entry<String, List<Object>> me2) {

        Object item1 = me1.getValue().get(compareIndex);
        Object item2 = me2.getValue().get(compareIndex);
        int compareResult = 0;

        if(item1 instanceof String && item2 instanceof String) {
            compareResult = ((String)item1).compareTo((String)item2);
        } else if(item1 instanceof Double && item2 instanceof Double) {
            compareResult = (int)((double)item1 - (double)item2);
        } else {
            // invalid comparison perhaps?
        }

        return compareResult;
    }
}
Aaron
  • 652
  • 4
  • 10
  • I've tried something similar to this, but I ran in to the issue that this isn't accepted as an override. My exact code header is: public > int compare(Map.Entry> map1, Map.Entry> map2) { ... } – wadda_wadda Sep 18 '13 at 21:27
  • @user130173 I've edited the example i provided with a working example. Construct the MyComparator with ALPHA_ZULU (0), and it will sort by index 0 of the value list. Use 1 to sort by the 1 index. If you're not on Java7 you'll need to copy the generic types in the diamond operator. – Aaron Sep 19 '13 at 16:51