Vic
Vic

Reputation: 211

Sorting Map keys when keys are arrays

I have a HashMap<Float[], Integer> and I'll probably need to convert it to TreeMap. How will keys (i.e. arrays) of TreeMap be sorted? By their first elements?

I was going to run a simple test but it resulted in error somehow:

public class treeMapTest {
    public static void main(String[] args) {
        Integer arr1[] = {9, 0, 3};
        Integer arr2[] = {2, 2, 2};
        Integer arr3[] = {4, 2, 1};

        TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>();
        tm.put(arr1, 7);
        tm.put(arr2, 7);
        tm.put(arr3, 7);

        System.out.println(tm);
    }
}

Thank you.

Upvotes: 3

Views: 83

Answers (5)

gati sahu
gati sahu

Reputation: 2626

You should provide Comparator in Treemap for you sorting preference.

public static void main(String[] args) {
            Integer arr1[] = {9, 0, 3};
            Integer arr2[] = {2, 2, 2};
            Integer arr3[] = {4, 2, 1};

            TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>(new Comparator<Integer[]>() {

                @Override
                public int compare(Integer[] o1, Integer[] o2) {
                    int cmp=o1[0].compareTo(o2[0]);
                    return cmp;
                }
            });
            tm.put(arr1, 7);
            tm.put(arr2, 7);
            tm.put(arr3, 7);
            for(Integer[] o1:tm.keySet())
            System.out.println(o1[0]);
        }

Upvotes: 1

tryingToLearn
tryingToLearn

Reputation: 11655

This might be syntactically correct but it's not practically useful. The map uses equals() method to determine whether 2 keys are equal. Arrays inherit equals() and hashcode() methods from Object class. Therefore when you want to search for a particular key(array object), you won't find it unless reference of the initial array object is passed. For e.g.

Integer arr1[] = {9, 0, 3};

and

Integer arr1_copy[] = {9, 0, 3};

are 2 different objects and default equals() will fail.

If however, you need to use arrays as key, what you can do instead is create a class with an array as it's member and override hashcode() and equals() methods for this class and use this class as key.

Upvotes: 2

jwenting
jwenting

Reputation: 5663

The keys areidentified by hashcode. That means the hashcode of the Array object representing the arrays, not the actual content of the array.

Which is most likely not what you had in mind, even if it may work for the scenario you're dealing with.

If you think that by moving elements around in the arrays you're going to change the sorting of the items in the value buckets of the hash map you're however sorely mistaken.

Upvotes: 1

Ted Cassirer
Ted Cassirer

Reputation: 364

Arrays does not have a natural ordering. One way to solve it and make it predictable would be to do something like this:

TreeMap<Integer[], Integer> tm = new TreeMap<>((a1, a2) -> Integer.compare(a1[0], a2[0]) );

This will compare the first element of each array. If the arrays can be empty you will need to alter it a little bit so it doesn't throw an exception.

Upvotes: 1

Eran
Eran

Reputation: 393841

Arrays don't have natural ordering (i.e. they don't implement the Comparable interface), which is why your code throws an exception when you instantiate the TreeMap using the parameterless constructor.

You must supply a Comparator<Integer[]> to the TreeMap constructor in order to define the ordering yourself.

BTW, using arrays as keys in a HashMap is a bad idea (since arrays don't override the default implementation of equals() and hashCode()), so it's a good thing you are switching to a TreeMap.

Upvotes: 5

Related Questions