Hashmap:只能得到最后一个值

And*_* Sh 1 java

我将一些数组放入带有2个键的hashmap中.然后我试图提取这些值,但只能获取最后一个键的值.对于任何其他键我得到空指针异常:

"线程中的异常"主"java.lang.RuntimeException:键没有xyValues:tmp.DataScan1.getSerie(DataScan1.java:49)位于tmp.DataScan1.main的数据为'L','18.'(DataScan1.java: 66)"

怎么了?

这是我的工作示例:

import java.util.Arrays;
import java.util.HashMap;

public class DataScan1 extends HashMap<Character, DataSerie>{
    public static double[] freqs;

    public void putSerie(char lriv, double freq, double[][] xyValues){

        char key1 = lriv;
        long key2 = double2key(round(freq, 4));

        DataSerie dataSerie = new DataSerie();

        dataSerie.put(key2, xyValues);
        this.put(key1, dataSerie);

    }

    private static long double2key(double value){
        long result = (long) (value * 10000);
        return result;      
    }

    public DataScan1(){

        freqs = new double[]{1, 16.9,4.0,18.2,17.4};

        for (int idxfreq=0; idxfreq<freqs.length; idxfreq++){

            double[][] array = new double[][]{{1, 2}, {3,4}};
            putSerie('L', freqs[idxfreq], array);

        }

    }

    public double[][] getSerie(char lriv, double freq){

        char key1 = lriv;
        long key2 = double2key(round(freq, 4));


            double[][] xyValues = this.get(key1).get(key2);
            if (xyValues == null){
                throw new RuntimeException("No xyValues for the keys: '" + lriv + "', '" + freq + "'");
            }
            return xyValues;

    }

    public static void printArr(double[] arr){
        System.out.println(Arrays.toString(arr));
    }

public static double round(double d, int decimalPlace) {
        BigDecimal bd = new BigDecimal(Double.toString(d));
        bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
        return bd.doubleValue();
    }




public static void main(String[] args) {
    DataScan1 myData = new DataScan1();
    printArr(myData.freqs);
    double[][] qq = myData.getSerie('L', 17.4); // that serie exist
    double[][] qqq = myData.getSerie('L', 18.2); // but this -- isn't, error here

}

}
Run Code Online (Sandbox Code Playgroud)

更新:我忘记了DataSerie定义:

public class DataSerie extends HashMap<Long, double[][]>{

}
Run Code Online (Sandbox Code Playgroud)

Gho*_*ica 7

简单地说:主意.

您希望使用浮点值作为Map的键.这意味着将创建Double对象; 并使用他们的equals()方法进行比较.

事情是:你不这样做.比较两个浮点数时,总是总是沿着(x1 - x2)<epsilon的行做某事.(请参阅此处了解更多示例,为什么这是一个坏主意;然后在这里寻找一些替代方案;最后在这里进行一些解释;尤其是Bernd的第2号回答)

换句话说:如果你真的想将这些数字用作键,那么将它们表示为字符串!

除此之外:避免混合概念 - 你决定使用地图; 所以不要通过使用数组使事情变得更复杂.我宁愿定义一个"Matrix"类来保存当前在double [] []数组中的内容.

最后,针对您当前代码的真正问题:

this.put(key1, dataSerie);
Run Code Online (Sandbox Code Playgroud)

在这里,您将新的dataSerie对象放入地图中.如果你仔细观察,你会发现你一直在使用相同的键(char'L').换句话说:是的,您的代码会创建一个新的dataSerie对象; 但随后要覆盖一个,在你的地图与价值的唯一条目.

因此,有两种方法:

  1. 如果此映射键始终相同的字符; 那么你不需要在这里使用地图.然后你将使用List并只添加你的值!
  2. 如果你的程序实际上必须处理不同的密钥,那么你最好使用一个Map<Char, List<double[][]>>例子.

但老实说; 我认为,真正带走这里是:退一步,并通过你的工作方式才能真正了解你要使用的东西!