3

I have this code:

    HashMap<String, String[]> unsorted = new HashMap<String, String[]>();
    String[] values = new String[3];
    String key;

    //add data to hashmap
    key = "abc";
    values[0] = "a"; values[1]="b"; values[2]="c";
    unsorted.put(key, values);

    key = "abc";
    values[0] = "aa"; values[1]="bb"; values[2]="cb";
    unsorted.put(key, values);

    key = "def";
    values[0] = "d"; values[1]="e"; values[2]="f";
    unsorted.put(key, values);

    //sort hashmap
    /***********/

    //output should be:
    { abc-[a,b,c], abc-[aa,bb,cc], def-[d,e,f] }

    //or

    { abc-[aa,bb,cc], abc-[a,b,c], def-[d,e,f] }

How can I sort it like that? Note: I tried with using TreeMap, and other examples, but they eliminate the elements where the keys are equal.

Edit: I solved my problem :) thanks to Guillaume. Here is what I used:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class test {

public static void main(String[] args) {

    ArrayList<CustomObject> objs = new ArrayList<CustomObject>();

    objs.add(new CustomObject("abc", new String[] {"a", "b", "c"}));
    objs.add(new CustomObject("def", new String[] {"d", "e", "f"}));
    objs.add(new CustomObject("abc", new String[] {"aa", "bb", "cc"}));


    System.out.println(objs.isEmpty());

    Collections.sort(objs, new Comparator<CustomObject>() {
        @Override
        public int compare(CustomObject o1, CustomObject o2) {
            int i = o1.getKey().compareTo(o2.getKey());
            if(i == 0)
                return -1;
            return i;
        }
    });

    for(int i=0; i<objs.size(); i++)
        System.out.println("key/value pair:" + objs.get(i).getKey() + " - " + objs.get(i).getValues()[0]);
    }
}

And the CustomObject:

public class CustomObject {

private String key;
private String[] values;

public CustomObject(String key, String[] values) {
    this.key = key;
    this.values = values;
}

public String getKey() {
    return key;
}

public String[] getValues() {
    return values;
}
}
2
  • 1
    A map is supposed to have only one element for each key. Why don't you put in string arrays in your TreeMap, as you do with the HashMap? Commented Dec 13, 2011 at 14:27
  • Note that, if you ever need to have your elements in a map in natural order based on a comparator, use the implementation TreeMap, not the HashMap. No Map implementation in the JDK allows duplicate keys. Commented Dec 13, 2011 at 14:45

4 Answers 4

5

If you need special ordering, and the ability to have multiple objects that have an equal "key", that screams for List, with a custom Comparator.

1- Define a class of elements to store in your list. In your case, it's an object that has 2 fields: a "key" and an array of String. Let's call it CustomObject (you can call it as you like)

2- Stick all your objects in the list

Like that:

list.add(new CustomObject("abc", new String[] {"a", "b", "c"});
list.add(new CustomObject("abc", new String[] {"aa", "bb", "cc"});
list.add(new CustomObject("def", new String[] {"d", "e", "f"});

3- Order your list using a custom comparator.

To order the list do

Collections.sort(list, new Comparator<CustomObject>() {
        @Override
        public int compare(CustomObject o1, CustomObject o2) {
            return o1.getArray().compare(o2.getArray());
        }
    });

(your comparator needs to be a bit more sophisticated, to properly compare arrays, but you see my point).


An alternative to that is to add a natural ordering to your CustomObject (implements Comparable), and stick them into a TreeSet.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, I'll try the first method, but do I have to define every function for the items list?? (public void add(int index, CustomObject element), public CustomObject get(int index), etc)
No, no, use an ArrayList :) I said List because it's the interface, use any of its implementations (ArrayList or LinkedList)
Glad it helped :) But really, you should find a proper name instead of CustomObject, something that describes what your objects are
3

The HashMap can not be sorted (or contain duplicate keys), it is part of how it is implemented (see the documentation).

This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

So you better do as other people are suggesting and switch to a list or a different map implementation.

Comments

2

You can also sort your hashmap using following method

private static HashMap sortByValues(HashMap map) {
        List list = new LinkedList(map.entrySet());
        // Defined Custom Comparator here
        Collections.sort(list, new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((Comparable) ((Map.Entry) (o1)).getValue())
                        .compareTo(((Map.Entry) (o2)).getValue());
            }
        });

        // Here I am copying the sorted list in HashMap
        // using LinkedHashMap to preserve the insertion order
        HashMap sortedHashMap = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            sortedHashMap.put(entry.getKey(), entry.getValue());
        }
        return sortedHashMap;
    }

call method like //shift your hashmap

 shift =sortByValues(shift)

Comments

0

You need to use a Map that allows duplicate keys, there is no such Map in the JDK. Try using a Multimap in Google guava. http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html

An implementation that have natural order is the TreeMultiMap: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/TreeMultimap.html

Good luck :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.