简体   繁体   中英

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 (ie 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.

Arrays don't have natural ordering (ie 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 .

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 eg

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.

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.

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.

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]);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM