在Java中使用数组作为散列键?
我有一个做一些计算的函数。它接受一个int数组,并根据传递给它的int数组的内容返回一个整数 由于我的应用程序正在进行数百次这些计算,我正在尝试设置一种方法,将这些计算结果存储在hashmap中,这样它就不必重新计算最近已经进行的计算。要做到这一点,我需要使用int数组作为hashmap的键 目前这是打印尺寸2,我希望它是打印尺寸1:在Java中使用数组作为散列键?,java,hashmap,Java,Hashmap,我有一个做一些计算的函数。它接受一个int数组,并根据传递给它的int数组的内容返回一个整数 由于我的应用程序正在进行数百次这些计算,我正在尝试设置一种方法,将这些计算结果存储在hashmap中,这样它就不必重新计算最近已经进行的计算。要做到这一点,我需要使用int数组作为hashmap的键 目前这是打印尺寸2,我希望它是打印尺寸1: LinkedHashMap hashmap = new LinkedHashMap(); int test[] = {1,2,3}; int test2[] =
LinkedHashMap hashmap = new LinkedHashMap();
int test[] = {1,2,3};
int test2[] = {1,2,3};
hashmap.put(test, 1);
hashmap.put(test2, 1);
System.out.println("Size: "+hashmap.size());
实现这一目标的最佳方式是什么?我可以创建一种方法,将数组转换为某种字符串编码数组数据,但我认为这不是最好的解决方案。它目前正在打印2,因为它们是两个不同的数组,具有两个不同的哈希代码,因此尽管它们具有相同的元素,但对于集合而言它们并不相同。您应该创建自己的对象,该对象内部有一个数组作为变量。然后它将重写equals和hashCode方法,以便根据数组中的值使值相同 e、 g:
我将创建特定于数组的键,然后将该键和计算结果存储在缓存中:
public static void main() {
Map<String, Integer> hashmap = new HashMap<>();
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
hashmap.put(Arrays.hashCode(arr1), 1);
hashmap.put(Arrays.hashCode(arr2), 1);
System.out.println("Size: "+hashmap.size());
}
publicstaticvoidmain(){
Map hashmap=新hashmap();
int[]arr1={1,2,3};
int[]arr2={1,2,3};
hashmap.put(Arrays.hashCode(arr1),1);
hashmap.put(Arrays.hashCode(arr2),1);
System.out.println(“Size:+hashmap.Size());
}
代码打印大小:1使用Apache commons方法创建唯一的数组键。它将数组作为参数,并对每个元素调用toString(),以获得每个元素的字符串表示形式。然后,如果指定了一个字符串,则每个元素字符串表示形式将被连接到一个字符串中,中间带有分隔符:
import org.apache.commons.lang3.StringUtils;
int[] a = {1, 2, 3}
String key= StringUtils.join(a, '-');
System.out.println(key);
产生:
1-2-3正如其他人所建议的,您应该创建一个类来包装数组,并以一致的方式实现
hashCode()
和equals()
其他答案要么建议将int[]
数组转换为字符串
,要么指示应迭代该数组以计算哈希值或检查是否相等
我建议您使用实用程序类有效地计算基于数组的哈希值,并检查数组是否相等:
public class Key {
private final int[] values;
public Key(int[] values) {
this.values = values;
}
@Override
public boolean equals(Object another) {
if (another == this) {
return true;
}
if (another == null) {
return false;
}
if (another.getClass() != this.getClass()) {
return false;
}
Key key = (Key) another;
return Arrays.equals(this.values, key.values);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.values);
}
}
然后,在地图中使用它:
Map<Key, Integer> map = new LinkedHashMap<>(); // preserve insertion order?
int test[] = {1, 2, 3};
int test2[] = {1, 2, 3};
Key key = new Key(test);
Key key2 = new Key(test2);
map.put(key, 1);
map.put(key2, 1);
map.size(); // 1
如果希望两个
键
在不考虑其数组元素顺序的情况下相等,则应在键
类的构造函数中将int[]
数组转换为散列集
,然后实现键
的等于()
方法通过在HashSet
中委托给它们各自的实现,您可以将列表
存储在hashmap中。您可以使用任何对象作为hashmap的键,出于您的目的,您可以使用一个列表或一个列表
,或者将数组包装在一个简单的类中,该类重写equals()
/hashCode()
;查看数组
类您应该查看Trove库。它支持原始集合、映射和自定义哈希策略。有人怎么看hashset?Gregory Basior answer更像Java-ish。这是不正确的,因为两个不同数组的哈希代码可能产生相同的值。这是使用键的equals操作来分割差异的地方,但是这种方法不能提供自定义equals操作。@Solubris为两个数组生成相同的哈希值是完全可以的,只要它们的内容相同。查看更多信息details@MaxXoom我说过两个不同的数组可以有相同的哈希代码,这就是数组中元素的值可以用来分隔键的地方,但是,由于只有哈希代码被用作键,因此数组的元素不可用于任何哈希查找,哈希映射是这样做的。@Solubris您能给出一个支持您的理论的代码示例吗?您可以使用Arrays.hashCode()
和Arrays.equals()
用于您的两个函数。由于某些原因,我认为此解决方案不起作用。首先,根据作者的问题,有数百个数组需要处理。此解决方案将为每个阵列创建一个对象,该对象可能会占用内存(如果涉及大量不同的阵列),并最终导致程序崩溃。其次,要有效地访问对象日志中的数组hashCode将存在一个问题。第三,该解决方案没有提供存储阵列计算结果的方法。那你在做什么?
Map<Key, Integer> map = new LinkedHashMap<>(); // preserve insertion order?
int test[] = {1, 2, 3};
int test2[] = {1, 2, 3};
Key key = new Key(test);
Key key2 = new Key(test2);
map.put(key, 1);
map.put(key2, 1);
map.size(); // 1
int[] v1 = {1, 2, 3};
int[] v2 = {2, 1, 3};
Key k1 = new Key(v1);
Key k2 = new Key(v2);
k1.equals(k2); // false!