Sorting map keys when keys are arrays

I have HashMap<Float[], Integer>

, and I will probably need to convert it to TreeMap

. How will the keys (i.e. Arrays) of the TreeMap be sorted? By your first elements?

I was about to run a simple test, but it somehow resulted in an error:

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.

+3


source to share


5 answers


Arrays do not have natural ordering (i.e. they do not implement an interface Comparable

), so your code throws an exception when you instantiate it TreeMap

using a parameterless constructor.

You have to provide a constructor to the Comparator<Integer[]>

constructor TreeMap

to define the order yourself.



BTW, using arrays as keys in HashMap

is a bad idea (since arrays don't override the default implementation equals()

and hashCode()

), so it's good that you switch to TreeMap

.

+5


source


This may be syntactically correct, but it is practically not useful. The map uses a method equals()

to determine if 2 keys are equal. Arrays inherit the methods equals()

and hashcode()

from the Object class. So when you want to find a specific key (array object), you won't find it unless a reference to the original array object is passed. For example,

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

      

and



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

      

- these are two different objects, and equals()

does not work by default .

If, however, you need to use arrays as key, instead, you can create a class with an array as a member and override methods hashcode()

, and equals()

for the class, and use this class as the key.

+2


source


Arrays are not naturally ordered. One way to solve it and make it predictable is 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 need to modify it slightly to exclude it.

+1


source


Keys are identified by hashcode. This means the hash code of the Array object representing the arrays, not the actual contents of the array.

This is most likely not what you meant, even if it might work for the scenario you are dealing with.

If you think that by moving the elements around the arrays you are going to change the sorting of the elements in the buckets of hashmap values, you are, however, very wrong.

+1


source


You should provide a Comparator in the Treemap for sorting.

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

      

+1


source







All Articles