我有一个可以进行一些计算的函数。它接受一个int数组,并根据传递给它的int数组的内容返回一个整数。
由于我的应用程序正在进行数百个这样的计算,我正在尝试设置一种方法将这些计算结果存储在一个hashmap中,这样就不必重新计算它最近已经完成的计算。为此,我需要使用int数组作为hashmap的键。
目前这是打印尺寸2,我希望它是打印尺寸1:
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());
实现这一目标的最佳方法是什么?我可以创建一个方法将数组转换为某种编码数组数据的字符串,但我认为这不是最好的解决方案。
答案 0 :(得分:3)
它当前正在打印2,因为它们是两个不同的数组,有两个不同的hashCodes,所以尽管它们具有相同的元素,但它们对于集合的目的而言并不相同。您应该创建自己的对象,该对象在Object内部有一个数组作为变量。然后它将覆盖equals和hashCode方法,以便根据数组中的值使值相同。
e.g:
public class MyClass
{
private int[] array;
public boolean equals(Object o)
{
if(! (o instance of MyClass) ) return false;
//loop through the arrays to see they are equal
}
public int hashCode()
{
//loop through the array and return a number that is based off of the values in the array such as array[0] ^ array[1] + array[2] * array[3] / array[4] ...
}
}
答案 1 :(得分:0)
我会创建数组特定的密钥,然后将密钥和计算结果存储在缓存中:
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());
}
代码打印尺寸:1
答案 2 :(得分:0)
使用Apache commons StringUtils.join()方法创建唯一的数组键。它将数组作为参数,并在每个元素上调用toString()以获取每个元素的字符串表示形式。然后将每个元素字符串表示连接成一个字符串,如果指定了一个字符串,则在它们之间使用分隔符:
import org.apache.commons.lang3.StringUtils;
int[] a = {1, 2, 3}
String key= StringUtils.join(a, '-');
System.out.println(key);
产地:
1-2-3
答案 3 :(得分:0)
正如其他人所建议的那样,你应该创建一个包装数组的类,并以一致的方式实现hashCode()
和equals()
。
其他答案建议您将int[]
数组转换为String
,或者指示您应该迭代它以计算哈希值或检查相等性。
我建议您使用Java's Arrays
实用程序类来有效地计算基于数组的哈希值并检查数组是否相等:
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
注意: Key
的此实现会考虑数组的元素顺序,这意味着两个Key
如果从两个具有不同顺序的相同元素的数组:
int[] v1 = {1, 2, 3};
int[] v2 = {2, 1, 3};
Key k1 = new Key(v1);
Key k2 = new Key(v2);
k1.equals(k2); // false!
如果您希望两个Key
尽管数组的元素顺序相同,则应将int[]
数组转换为HashSet
中的Key
类的构造函数,然后通过委派Key
中各自的实现来实现equals()
的{{1}}和hashCode()
方法。