是否可以在java中使用数组作为映射键?

时间:2016-04-02 14:38:23

标签: java

Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>();

我正在尝试使用数组中的两个整数作为键并使用不同的int作为值。这些阵列都是独一无二的。但是,我不断收到java.lang.classcastexception错误。任何建议?

3 个答案:

答案 0 :(得分:1)

更新:提及托马斯,您可以将自定义Comparator传递给TreeMap。因此,您的原始代码可以稍作修改:

Map<Integer[], Integer> map = new TreeMap<Integer[], Integer>(new IntegerWordComparator());

在这种情况下,IntegerWordComparator将类似于IntegerWord(见下文),但作为Comparator界面的实现:

public class IntegerWordComparator implements Comparator<Integer[]> {

    @Override
    public int compare(Integer[] iw1, Integer[] iw2) {
        int commonLength = Math.min(iw1.length, iw2.length);
        for (int i = 0; i < commonLength; i++) {
            if (iw1[i] > iw2[i]) {
                return 1;
            } else if (iw1[i] < iw2[i]) {
                return -1;
            }
        }
        if (iw1.length > iw2.length) {
            return 1;
        } else if (iw1.length < iw2.length) {
            return -1;
        } else {
            return 0;
        }
    }

}

原始答案

使用List代替数组,使用HashMap代替TreeMap

Map<List<Integer>, Integer> map = new HashMap<List<Integer>, Integer>();

// add three items two of which are the same
map.put(Arrays.asList(new Integer[]{1, 2, 3}), 1);
map.put(Arrays.asList(new Integer[]{3, 4, 7}), 2);
map.put(Arrays.asList(new Integer[]{1, 2, 3}), 4);

// print the size
System.out.println(map.size()); // 2

如果您想忽略订单,请使用Set作为密钥。

如果您真的想使用TreeMap并且想要按字典顺序比较数组,那么您可以编写自己的类并将其用作关键字。这是一个例子:

public class IntegerWord implements Comparable<IntegerWord> {

    protected final Integer[] integers;

    public IntegerWord(Integer... integers) {
        this.integers = integers;
    }

    @Override
    public int compareTo(IntegerWord other) {
        int commonLength = Math.min(integers.length, other.integers.length);
        for (int i = 0; i < commonLength; i++) {
            if (integers[i] > other.integers[i]) {
                return 1;
            } else if (integers[i] < other.integers[i]) {
                return -1;
            }
        }
        if (integers.length > other.integers.length) {
            return 1;
        } else if (integers.length < other.integers.length) {
            return -1;
        } else {
            return 0;
        }
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof IntegerWord) {
            return (compareTo((IntegerWord)other) == 0);
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return Arrays.asList(integers).toString();
    }

}

用法:

Map<IntegerWord, Integer> map = new TreeMap<IntegerWord, Integer>();
map.put(new IntegerWord(2, 5), 11);
map.put(new IntegerWord(1, 2, 3), 22);
map.put(new IntegerWord(1, 2, 3, 4), 33);
map.put(new IntegerWord(1, 2, 3), 44); // 1, 2, 3 again!
map.put(new IntegerWord(3, 9, 3, 4), 55);
map.put(new IntegerWord(0, 1), 66);
map.put(new IntegerWord(), 77); // will be the first!
System.out.println(map);

答案 1 :(得分:0)

这是一个使用HashMap而不是TreeMap的工作示例。

import java.util.HashMap;
import java.util.Map;
public class Test {
  public static void main(String[] args) {
    Map<Integer[], Integer> map = new HashMap<Integer[], Integer>();
    Integer[] array1 = {1, 2, 3};
    Integer[] array2 = {4, 5, 6};

    map.put(array1, 42);
    map.put(array2,  -1000);
    System.out.println("array1: "+map.get(array1));
  }
}

答案 2 :(得分:0)

数组没有实现equals()和hashCode(),所以如果你使用数组作为键,你只能使用完全相同的数组来获取值。

Integer[] key1 = {1, 2, 3};
Integer[] key2 = {1, 2, 3};
System.out.println(key1.equals(key2)); //false
System.out.println(key1.hashCode() == key2.hashCode()); //false

Map<Integer[], String> map = new HashMap<>();
map.put(key1, "value");
System.out.println(map.get(key1)); //value
System.out.println(map.get(key2)); //null

最好创建这样的包装器:

class IntArrayKey {
    Integer[] array;

    public IntArrayKey(Integer... array) {
        this.array = array;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        IntArrayKey that = (IntArrayKey) o;
        return Arrays.equals(array, that.array);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(array);
    }
}

P.S。要与TreeMap一起使用,您可以实现Comparable