我将一些数组放入带有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)
简单地说:坏主意.
您希望使用浮点值作为Map的键.这意味着将创建Double对象; 并使用他们的equals()方法进行比较.
事情是:你不这样做.比较两个浮点数时,总是总是沿着(x1 - x2)<epsilon的行做某事.(请参阅此处了解更多示例,为什么这是一个坏主意;然后在这里寻找一些替代方案;最后在这里进行一些解释;尤其是Bernd的第2号回答)
换句话说:如果你真的想将这些数字用作键,那么将它们表示为字符串!
除此之外:避免混合概念 - 你决定使用地图; 所以不要通过使用数组使事情变得更复杂.我宁愿定义一个"Matrix"类来保存当前在double [] []数组中的内容.
最后,针对您当前代码的真正问题:
this.put(key1, dataSerie);
Run Code Online (Sandbox Code Playgroud)
在这里,您将新的dataSerie对象放入地图中.如果你仔细观察,你会发现你一直在使用相同的键(char'L').换句话说:是的,您的代码会创建一个新的dataSerie对象; 但随后要覆盖一个,在你的地图与价值的唯一条目.
因此,有两种方法:
Map<Char, List<double[][]>>例子.但老实说; 我认为,真正带走这里是:退一步,并通过你的工作方式这才能真正了解你要使用的东西!
| 归档时间: |
|
| 查看次数: |
608 次 |
| 最近记录: |