LinkedHashMap<double[], Integer>,无法使用 .get 或 .containsKey 访问 Integer
LinkedHashMap<double[], Integer>, cannot access Integer with .get or .containsKey
我有一系列小数组(由两个双精度数组成),其中很多是
相同。例如
{5.0, 15.0}
{5.0, 15.0}
{5.0, 15.0}
{12.0, 8.0}
{10.0, 8.0}
{10.0, 8.0}
我希望能够计算每个数组的数量,即
3 of {5.0, 15.0}
1 of {12.0, 8.0}
2 of {10.0, 8.0}
为此,我尝试使用 LinkedHashMap(链接,因为顺序
以后可能会用到):
import java.util.Map;
import java.util.LinkedHashMap;
public class MapArrayInt {
Map<double[], Integer> arrays = new LinkedHashMap<double[], Integer>();
public static void main(String[] args) {
MapArrayInt mapArrayInt = new MapArrayInt();
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(12.0, 8.0);
mapArrayInt.addArray(10.0, 8.0);
mapArrayInt.addArray(10.0, 8.0);
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{5.0, 15.0})));
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{12.0, 8.0})));
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{10.0, 8.0})));
}
void addArray(double val1, double val2) {
double[] newArray = new double[]{val1, val2};
if (!arrays.containsKey(newArray)) {
arrays.put(newArray, 1);
} else {
arrays.put(newArray, arrays.get(newArray) + 1);
}
}
}
我期待这个输出,
3
1
2
但是得到了,
null
null
null
我对 Java 很陌生,但我怀疑这可能是因为每个 double[]
都算作唯一,因为它们是不同的实例,即使它们包含相同的两个双打。
我该如何解决这个问题(是否有更好的方法)?我只需要一个允许我
的数据结构
- 添加
doubles[]
- 保留
doubles[]
的顺序
- 轻松迭代得到
doubles[]
和所述doubles[]
的数量
正如我在评论中所述,使用 new
您正在创建对象的新实例。这意味着您使用 mapArrayInt.addArray(5.0, 15.0);
添加的数组和 mapArrayInt.arrays.get(new double[]{5.0, 15.0})
中的数组引用 不同的 对象。这就是你得到 null
的原因,因为对于地图来说,它们是不同的键。
为了避免这种情况,您可以创建一个自定义包装器 class
import java.util.Arrays;
public class Exercise {
private final double[] array;
public Exercise(double first, double second) {
this.array = new double[]{first, second};
}
public boolean equals(Object obj) {
if(!(obj instanceof Exercise)) {
return false;
}
Exercise other = (Exercise)obj;
return Arrays.equals(this.array, other.array);
}
public int hashCode() {
return Arrays.hashCode(array);
}
}
equals
和 hashCode
方法很重要,当你想在像 Map
这样的集合中使用这个 class 时,否则 Object
的哈希码用于检查相等性,您会遇到与现在相同的问题。
然后,在你的主 class 中你可以像这样使用它:
void addArray(double val1, double val2) {
Exercise exercise = new Exercise(val1, val2);
if (!arrays.containsKey(exercise)) {
arrays.put(exercise, 1);
} else {
arrays.put(exercise, arrays.get(exercise) + 1);
}
}
和System.out.println(String.valueOf(mapArrayInt.arrays.get(new Exercise(5.0, 15.0))));
编辑:
我把一个double改成了int(你说你代表的是reps和weight ...reps只能是自然数对吧?)
您可以像下面这样创建一个练习-Class,并使用静态方法"of"创建实例:
package somepackage;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class Exercise
{
private static final Map<Integer, Map<Double, WeakReference<Exercise>>> instances = new HashMap<>();
private final int reps;
private final double weight;
private Exercise(int reps, double weight)
{
this.reps = reps;
this.weight = weight;
}
public static Exercise of(int reps, double weight)
{
if (!instances.containsKey(reps))
{
instances.put(reps, new HashMap<>());
}
Map<Double, WeakReference<Exercise>> innerMap = instances.get(reps);
WeakReference<Exercise> weakRef = innerMap.get(weight);
Exercise instance = null;
if (weakRef != null)
{
instance = weakRef.get();
}
if (weakRef == null || instance == null || weakRef.isEnqueued())
{
instance = new Exercise(reps, weight);
innerMap.put(weight, new WeakReference<>(instance));
}
return instance;
}
public int getReps()
{
return this.reps;
}
public double getWeight()
{
return this.weight;
}
}
然后你可以将这些练习放在如下图中:
public void addArray(int reps, double weight)
{
Exercise exercise = Exercise.of(reps, weight);
if (!arrays.containsKey(exercise))
{
arrays.put(exercise, 1);
}
else
{
arrays.put(exercise, arrays.get(exercise) + 1);
}
}
或:
您可以使用 Map<Double, Integer>
作为 2 个值的值,而不是 double[]
作为键:
package somepackage;
import java.util.HashMap;
import java.util.Map;
public class MapArrayInt
{
private final Map<Double, Map<Double, Integer>> values;
public MapArrayInt()
{
this.values = new HashMap<>();
}
public void addArray(double val1, double val2)
{
if (!this.values.containsKey(val1))
{
this.values.put(val1, new HashMap<>());
}
Map<Double, Integer> innerValues = this.values.get(val1);
if (innerValues.containsKey(val2))
{
innerValues.put(val2, innerValues.get(val2) + 1);
}
else
{
innerValues.put(val2, 1);
}
}
public int getArrayValue(double val1, double val2)
{
Map<Double, Integer> innerValues = this.values.get(val1);
if (innerValues == null)
{
// you may also throw an Exception here
return 0;
}
Integer value = innerValues.get(val2);
if (value == null)
{
// also here you may throw an Exception
return 0;
}
return value;
}
public int getArrayValue(double[] values)
{
return getArrayValue(values[0], values[1]);
}
}
我有一系列小数组(由两个双精度数组成),其中很多是 相同。例如
{5.0, 15.0}
{5.0, 15.0}
{5.0, 15.0}
{12.0, 8.0}
{10.0, 8.0}
{10.0, 8.0}
我希望能够计算每个数组的数量,即
3 of {5.0, 15.0}
1 of {12.0, 8.0}
2 of {10.0, 8.0}
为此,我尝试使用 LinkedHashMap(链接,因为顺序 以后可能会用到):
import java.util.Map;
import java.util.LinkedHashMap;
public class MapArrayInt {
Map<double[], Integer> arrays = new LinkedHashMap<double[], Integer>();
public static void main(String[] args) {
MapArrayInt mapArrayInt = new MapArrayInt();
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(5.0, 15.0);
mapArrayInt.addArray(12.0, 8.0);
mapArrayInt.addArray(10.0, 8.0);
mapArrayInt.addArray(10.0, 8.0);
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{5.0, 15.0})));
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{12.0, 8.0})));
System.out.println(String.valueOf(mapArrayInt.arrays.get(new double[]{10.0, 8.0})));
}
void addArray(double val1, double val2) {
double[] newArray = new double[]{val1, val2};
if (!arrays.containsKey(newArray)) {
arrays.put(newArray, 1);
} else {
arrays.put(newArray, arrays.get(newArray) + 1);
}
}
}
我期待这个输出,
3
1
2
但是得到了,
null
null
null
我对 Java 很陌生,但我怀疑这可能是因为每个 double[]
都算作唯一,因为它们是不同的实例,即使它们包含相同的两个双打。
我该如何解决这个问题(是否有更好的方法)?我只需要一个允许我
的数据结构- 添加
doubles[]
- 保留
doubles[]
的顺序
- 轻松迭代得到
doubles[]
和所述doubles[]
的数量
正如我在评论中所述,使用 new
您正在创建对象的新实例。这意味着您使用 mapArrayInt.addArray(5.0, 15.0);
添加的数组和 mapArrayInt.arrays.get(new double[]{5.0, 15.0})
中的数组引用 不同的 对象。这就是你得到 null
的原因,因为对于地图来说,它们是不同的键。
为了避免这种情况,您可以创建一个自定义包装器 class
import java.util.Arrays;
public class Exercise {
private final double[] array;
public Exercise(double first, double second) {
this.array = new double[]{first, second};
}
public boolean equals(Object obj) {
if(!(obj instanceof Exercise)) {
return false;
}
Exercise other = (Exercise)obj;
return Arrays.equals(this.array, other.array);
}
public int hashCode() {
return Arrays.hashCode(array);
}
}
equals
和 hashCode
方法很重要,当你想在像 Map
这样的集合中使用这个 class 时,否则 Object
的哈希码用于检查相等性,您会遇到与现在相同的问题。
然后,在你的主 class 中你可以像这样使用它:
void addArray(double val1, double val2) {
Exercise exercise = new Exercise(val1, val2);
if (!arrays.containsKey(exercise)) {
arrays.put(exercise, 1);
} else {
arrays.put(exercise, arrays.get(exercise) + 1);
}
}
和System.out.println(String.valueOf(mapArrayInt.arrays.get(new Exercise(5.0, 15.0))));
编辑: 我把一个double改成了int(你说你代表的是reps和weight ...reps只能是自然数对吧?)
您可以像下面这样创建一个练习-Class,并使用静态方法"of"创建实例:
package somepackage;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class Exercise
{
private static final Map<Integer, Map<Double, WeakReference<Exercise>>> instances = new HashMap<>();
private final int reps;
private final double weight;
private Exercise(int reps, double weight)
{
this.reps = reps;
this.weight = weight;
}
public static Exercise of(int reps, double weight)
{
if (!instances.containsKey(reps))
{
instances.put(reps, new HashMap<>());
}
Map<Double, WeakReference<Exercise>> innerMap = instances.get(reps);
WeakReference<Exercise> weakRef = innerMap.get(weight);
Exercise instance = null;
if (weakRef != null)
{
instance = weakRef.get();
}
if (weakRef == null || instance == null || weakRef.isEnqueued())
{
instance = new Exercise(reps, weight);
innerMap.put(weight, new WeakReference<>(instance));
}
return instance;
}
public int getReps()
{
return this.reps;
}
public double getWeight()
{
return this.weight;
}
}
然后你可以将这些练习放在如下图中:
public void addArray(int reps, double weight)
{
Exercise exercise = Exercise.of(reps, weight);
if (!arrays.containsKey(exercise))
{
arrays.put(exercise, 1);
}
else
{
arrays.put(exercise, arrays.get(exercise) + 1);
}
}
或:
您可以使用 Map<Double, Integer>
作为 2 个值的值,而不是 double[]
作为键:
package somepackage;
import java.util.HashMap;
import java.util.Map;
public class MapArrayInt
{
private final Map<Double, Map<Double, Integer>> values;
public MapArrayInt()
{
this.values = new HashMap<>();
}
public void addArray(double val1, double val2)
{
if (!this.values.containsKey(val1))
{
this.values.put(val1, new HashMap<>());
}
Map<Double, Integer> innerValues = this.values.get(val1);
if (innerValues.containsKey(val2))
{
innerValues.put(val2, innerValues.get(val2) + 1);
}
else
{
innerValues.put(val2, 1);
}
}
public int getArrayValue(double val1, double val2)
{
Map<Double, Integer> innerValues = this.values.get(val1);
if (innerValues == null)
{
// you may also throw an Exception here
return 0;
}
Integer value = innerValues.get(val2);
if (value == null)
{
// also here you may throw an Exception
return 0;
}
return value;
}
public int getArrayValue(double[] values)
{
return getArrayValue(values[0], values[1]);
}
}