-4

I saw this thread sorting a List of Map<String, String> and I know mine could sound a duplicate, but it is slight differen.

My example is:

List<Map<String, String>> myList = new ArrayList<Map<String, String>>();

...
for(MyClass1 c1 : c1)
{
  ...
  for(MyClass2 c2 : c12)
  {
    SimpleBindings myBindindings= new SimpleBindings();
    myBindindings.put(c1.getName(), c2.getName());

    myList.add(myBindindings);
  }
}
...

Concretely I can have

{
 (John, Mike)
 (John, Jack)
 (Sam, Jack)
 (Gloria, Anna)
 (Jane, Carla)
 ...
}

and would like that my list is sorted by the maps key:

{
  (Gloria, Anna)
  (Jane, Carla)
  (John, Mike)
  (John, Jack)
  (Sam, Jack)
  ...
}
Community
  • 1
  • 1
Francesco
  • 2,350
  • 11
  • 36
  • 59
  • 2
    How is it different? Did you try writing a Comparator like the answers suggested? What did you try? – forgivenson Sep 05 '14 at 12:55
  • 1
    What are you sorting exactly? You have a `List` (a collection) of `Map` (another collection). How do you determine whether one `Map` is greater than another? Also, you are adding `SimpleBindings` not `Map` - if this class `extends Map` consider _not_ doing so as extending items in the Java collections framework is best avoided. – Boris the Spider Sep 05 '14 at 12:55
  • 2
    So your `Map`s are only 1 key-value pair each? Why not just use a `TreeMap` for the whole thing? – Mena Sep 05 '14 at 12:56
  • 2
    @Mena that is my suspicion too - if this is the case than `Map` is the wrong structure entirely as lookup is evidently not required. `TreeSet` of some custom object would probably be best. – Boris the Spider Sep 05 '14 at 12:57
  • @Mena A single tree map won't work, since there seem to be duplicate keys. But maybe a `List`... – tobias_k Sep 05 '14 at 12:59
  • @BoristheSpider true, a `TreeSet` of, say, `User` might be more suitable. I was thinking `Map` because of the 1st name -> surname representation but at this point OP's scope is quite obscure. – Mena Sep 05 '14 at 13:00
  • @BoristheSpider He probably means `javax.script.SimpleBinding` which already extends `Map` – tobias_k Sep 05 '14 at 13:00
  • @tobias_k You're totally right. Which validates BoristheSpider's comment even more. – Mena Sep 05 '14 at 13:01
  • 1
    Why is `(John, Mike)` before `(John, Jack)` ? – Betlista Sep 05 '14 at 13:03
  • You were right. `Map` was a totally false choice. For what I need, a `List` of `Pair` is good enough... – Francesco Sep 08 '14 at 13:49

3 Answers3

1

Are you sure that

List<Map<String, String>>

is the approriate data type you want?

To me it looks like you are in fact looking simplify for

TreeMap<String, String>

i.e. a sorted map key -> value?

Or do you mean to use a List<StringPair> (for that, please choose a more appropriate name than StringPair, and implement that class to your needs)? I have the impression that in lack of an obvious Pair<String, String> class in Java you have been abusing SimpleBinding as a pair class. The proper way to have pairs in Java is to implement a new class, with a proper class name - "pair" is technical, not semantic.

You could also do

List<String[]>

and implement a Comparator<String[]> for sorting. But that doesn't save you any work over implementing a NamePair class and making it comparable yourself.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
0

You need to implement Comparator to accomplish this...

Collections.sort(myList, new Comparator<ObjectBeingCompared>() {

            @Override
            public int compare(ObjectBeingCompared obj1, ObjectBeingCompared obj2) {

                //Of course you will want to return 1, 0, -1 based on whatever you like
                //this is just a simple example 
                //return 1 if obj1 should be ordered first
                //return 0 if obj1 and obj2 are the same
                //return -1 if obj1 should be ordered after obj2
                return obj1.compareTo(obj2);
            }
        });
Jason Palmer
  • 99
  • 2
  • 8
-1

The HashMap data structure is used to allow access to its elements in O(1) time.

Because it is a container of data its pool or keys can vary in time. This mean that you can not assure in long therm an order for list of maps.

In your example you match two Strings and create Pair of data called SimpleBindings.

In case of your simple example you should not use Map<String,String> data structure to represent a Pair of data.

If you SimpleBindings really consist of two string, everything you must do is only implement a Comparable in SimpleBindings class like this:

class SimpleBinding implements  Comparable<SimpleBinding> {

    private final String key;
    private final String value;

    public SimpleBinding(String key, String value) {
        Objects.nonNull(key);
        Objects.nonNull(value);
        this.key = key;
        this.value = value;

    }

    @Override
    public int compareTo(SimpleBinding that) {
        return this.key.compareTo(that.key);
    }
}

And the you just use the Collections.sort(bindings ) to have sorted result.

In case you do not have access to the class you should use the Comparator interface like this

enum SimpleBindingComparator implements Comparator<SimpleBinding> {
     DEFUALT {
         @Override
         public int compare(SimpleBinding fist, SimpleBinding second) {
             return fist.key.compareTo(second.key);
         }
     };

Then you sort your bindings like this Collections.sort(bindings ,SimpleBindingComparator.DEFAULT);

But if your case is more complex than this and your store a Map in the list you should define a logic that represent the order. In your case it can be sad that the order must maintained by c1.getName()

One choice is that you should not create a List but a map of list Map<String>,List<String>> this is so called multi map where a single key matches to multiple values. See MultiMap of guava and if you want it to be sorted then i propose to read about TreeMultiMap

  • This creates a copy of the keys in a `Map` and sorts _the copy_. This neither sorts the `Map` nor answers the OP's question about sorting a `List>`. – Boris the Spider Sep 05 '14 at 13:10
  • The answer refer more to the output rather the code OP has presented. And is valid from that point of view. In general you can not sort a Map. Map is data container. What i have done is created and index to the map. (I did not copied the data only the references), and used it to display the result in demanded order. – Damian Leszczyński - Vash Sep 05 '14 at 13:17
  • Of course you can sort a `Map`. You need two things, 1) a `LinkedHashMap` and 2) a `Comparator`. But that is besides the point. The OP says that sorting of a `List>` is required not a sorting of the `Map`s _in_ the `List`. – Boris the Spider Sep 05 '14 at 13:24
  • No. LinkedHashMap will resolve you the items in order they ware put into list. The Comparator is used when you use TreeMap structure. What OP is missing is concept of multi Map. AS you can not specyfie the order of map as when you add itme to it all container that store the "order" would have to be rebuild. But you have some point with that. I will update my answer. That i hope will meet your criteria and OP problem as well. – Damian Leszczyński - Vash Sep 05 '14 at 13:31
  • Indeed - sort the entries as you wish using the `Comparator` and stick them into the `LinkedHashMap`. Sorted map, magic. A `TreeMap` has different behaviour characteristics and different method complexities, it is a different animal entirely. Whist a `Multimap` of some kind may be relevant, with more information on why the OP is using a [`SimpleBindings`](http://docs.oracle.com/javase/7/docs/api/javax/script/SimpleBindings.html) it's hard to say. – Boris the Spider Sep 05 '14 at 14:25