LinkedHashMap <double [],integer =“”>,无法使用.get或.containsKey

时间:2017-06-29 22:43:46

标签: java arrays data-structures hashmap linkedhashmap

我有一系列小阵列(由两个双打组成),其中很多都是 相同。 E.g。

{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[]都是唯一的,因为它们是不同的实例,即使它们包含相同的两个双精度。

如果我应该(有更好的方法),我怎么能解决这个问题呢?我只需要一个允许我

的数据结构
  1. 添加doubles[]
  2. 保留doubles[]
  3. 的顺序
  4. 轻松迭代以获取doubles[]和所述doubles[]
  5. 的数量

2 个答案:

答案 0 :(得分:3)

正如我在评论中所述,new您正在创建对象的新实例。这意味着您使用mapArrayInt.addArray(5.0, 15.0);添加的数组和mapArrayInt.arrays.get(new double[]{5.0, 15.0})中的数组引用不同的对象。这就是你获得null的原因,因为对于地图来说,这些是不同的密钥。

为了避免这种情况,您可以创建自定义包装类

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等集合中使用此类,hashCodeMap方法很重要,否则Object的哈希码用于检查相等性你现在遇到了同样的问题。

然后,在您的主要课程中,您可以像这样使用它:

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

答案 1 :(得分:2)

编辑: 我将其中一个双打更改为int(你说你代表的是代表和重量......并且代表只能是一个自然数字吗?)

您可以构建如下所示的创建练习类,并使用静态方法“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);
    }
}

OR: 您可以使用double[]作为2值的值来代替Map<Double, Integer>作为关键字:

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