-4

I have an ArrayList<HashMap<String,String>>.

Is there a way to change the order of the array of HashMaps? For example, if the String "firstName" is inside the HashMap, can I sort my ArrayList of HashMaps by that value? Just to be clear, I do not need to order keys and objects inside HashMaps. I need order HashMaps inside Arraylist.

What is a best way?

i tried to do from examples:

class MapComparator implements Comparator<HashMap<String, String>>
{
    private final String key;

    public MapComparator(String key)
    {
        this.key = key;
    }

    public int compare(HashMap<String, String> first,
            HashMap<String, String> second)
    {
        // TODO: Null checking, both for maps and values
         String firstName1 = first.get(key);
            String firstName2 = second.get(key);
            if(firstName1 == null)
                if(firstName2 == null)
                    return 0;
                else
                    return -1; // treat null as less than any non-null
            else
                if(firstName2 == null)
                    return 1; // treat null as less than any non-null
                else
                    return firstName1.compareTo(firstName2);

    }
}

and using:

                Log.e(THIS_FILE, "before ->" + addedRows);
                Collections.sort(addedRows, new MapComparator("name"));
                Log.e(THIS_FILE, "after ->" + addedRows);

and nothing sorted (to be sure i renamed one contact to start by letter a, hashmap with name=as ice:) must be first):

> E/ContactsActivity(23571): before ->[{type=, contactID=4, name=Office
> O}, {type=, contactID=2912, name=Test Text Last}, {type=,
> contactID=2915, name=as ife:) Eng}, {type=, contactID=2914,
> name=life:) Rus}, {type=, contactID=2913, name=life:) Ukr}, {type=,
> contactID=2897, name=дима куплеватскиц}] E/ContactsActivity(23571):
> after ->[{type=, contactID=4, name=Office O}, {type=, contactID=2912,
> name=Test Text Last}, {type=, contactID=2915, name=as ife:) Eng},
> {type=, contactID=2914, name=life:) Rus}, {type=, contactID=2913,
> name=life:) Ukr}, {type=, contactID=2897, name=дима куплеватскиц}]
user170317
  • 1,152
  • 2
  • 11
  • 22
  • 1
    actually this is a more Java answer than Android http://stackoverflow.com/questions/5369573/how-sort-an-arraylist-of-hashmaps-holding-several-key-value-pairs-each – Pavlos Dec 20 '12 at 18:22
  • 1
    `HashMap`s are unordered. Try a `TreeMap` instead. – Louis Wasserman Dec 20 '12 at 18:24
  • if you have any issue in using `TreeMap` then see this post for [how-to-sort-a-mapkey-value-on-the-values-in-java](http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java) – ρяσѕρєя K Dec 20 '12 at 18:31
  • @Παύλος i don't understand, why u put minuses to question without understanding, what is inside. You example about "duplicated" doesn't work. Thank you for understanding and i hope minused will go down – user170317 Dec 20 '12 at 18:42
  • I wasnt the one to add a minus in your question. Think before you say something – Pavlos Dec 20 '12 at 18:46
  • sorry :( i just was surprised, why community don't like question, it's a good question and i was investigate problem before make post – user170317 Dec 20 '12 at 19:52

2 Answers2

3

I believe the problem you are having is that a HashMap is completely unordered. If you want to add order to the data in a HashMap, the classic solution is to use a TreeMap.

Depending on your situation, perhaps you cannot start out using a TreeMap. If so, you will want to convert your HashMap to a TreeMap:

TreeMap treeMap = new TreeMap();
treeMap.putAll(hashMap);           // where "hashmap" was already filled

The resulting TreeMap will be ordered based upon the "keys" of your HashMap.

However, if you want to add order to the data in an , the classic solution is similarly to use a TreeList.

If you want to sort an ArrayList of HashMaps using values inside your each HashMap, all you need to do is create a TreeMap and place it into a TreeList. If you want to sort your ArrayList by something other than the keys of the original HashMap, you have a problem and will need to rethink your choice of data structure.

john_science
  • 6,325
  • 6
  • 43
  • 60
  • 3
    Note: you'll probably want to order a copy of the original data structure, not the original itself. – mre Dec 20 '12 at 18:29
  • 1
    Good call, I added a snippet of code for that to my response. – john_science Dec 20 '12 at 18:35
  • This is defenetely wrong answer. Please see my edited question. i Don't need to sort keys and volumes inside HashMap. i have to sort HASHMAPS inside ArrayList – user170317 Dec 20 '12 at 18:43
  • Sorry, I did not gather that from your original post. I have edited your post and my answer to try to clarify the idea: you want to sort an ArrayList of HashMaps based upon a object inside the HashMaps. – john_science Dec 20 '12 at 18:58
  • @theJollySin this is correct, this is what i want, unfortunately your answer not cover my task :( – user170317 Dec 20 '12 at 19:42
  • @user170317 Can you explain what you want? – john_science Dec 21 '12 at 03:00
2

It sounds like what you want is:

java.util.Collections.sort
(
    list,
    new java.util.Comparator<Map<String,String>>()
    {
        public int compare(Map<String,String> map1, Map<String,String> map2)
        {
            String firstName1 = map1.get("firstName");
            String firstName2 = map2.get("firstName");
            if(firstName1 == null)
                if(firstName2 == null)
                    return 0;
                else
                    return -1; // treat null as less than any non-null
            else
                if(firstName2 == null)
                    return 1; // treat null as less than any non-null
                else
                    return firstName1.compareTo(firstName2);
        }
    }
);

(where list is the name of your variable of type ArrayList<HashMap<String,String>>).

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • looks much better than previous examples - let me do it inside code – user170317 Dec 20 '12 at 18:59
  • unfortunately, doesn't work – user170317 Dec 20 '12 at 19:05
  • i was update question with you code... can u change your snippet? – user170317 Dec 20 '12 at 19:08
  • @user170317: It looks like it *did* work: the maps end up in sorted order by `name`. First `Office O`, then `Test Text Last`, then `life:) Eng`, then `life:) Rus`, then `life:) Ukr`, then `дима куплеватскиц`. Is that not what you want? – ruakh Dec 20 '12 at 19:15
  • to be sure, i was renamed one contact, but order of hash'es still same :( – user170317 Dec 20 '12 at 19:39
  • @user170317: Well, sure, if you sort an already-sorted list, then its order won't change. If you want to see it in action, try sorting by `contactID` instead of `name`. – ruakh Dec 20 '12 at 19:54
  • look to list now, one name there was changed and start from a - it have to be first, but first is still Office – user170317 Dec 20 '12 at 20:17
  • @user170317: You seem to be confused. `O` comes *before* `a` in Unicode order. For a case-insensitive comparison, you can try `firstName1.compareToIgnoreCase(firstName2)` instead of `firstName1.compareTo(firstName2)`; but even that will not do anything particularly intelligent when you mix different scripts (e.g. Latin and Cyrillic), as your example does. – ruakh Dec 20 '12 at 20:22