你好士兵们。
显然,哈希图中的键是唯一。但是,我一直在尝试编写一个读取csv文件的代码,然后将键和值放在映射中。但是,有相同的键(每个键在csv文件中是15次)。在这种情况下,它应该使值的总和,并只返回一次键。 怎么做?我现在的代码如下。
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader(filepath));
} catch (FileNotFoundException fnfex) {
System.out.println(fnfex.getMessage() + "Bestand niet gevonden!");
System.exit(0);
}
//this is where we read lines
try {
while((line = br.readLine()) != null) {
String[] splitter = line.split(cvsSplitBy);
if(splitter[0] != "Voertuig") {
alldataMap.put(splitter[0], splitter[8]);
}
//MIGHT BE JUNK, DONT KNOW YET
/*if((splitter[0].toLowerCase()).contains("1")){
double valuekm = Double.parseDouble(splitter[8]);
license1 += valuekm;
System.out.println(license1);
}
else {
System.out.println("not found");
}*/
}
System.out.println(alldataMap);
TextOutput();
} catch (IOException ioex) {
System.out.println(ioex.getMessage() + " Error 1");
} finally {
System.exit(0);
}
所以,如果我有以下信息(在这种情况下,它的第0和第8个字读取csv文件中的每一行)
Apples; 299,9
Bananas; 300,23
Apples; 3912,1
Bananas;342
Bananas;343
它应该返回
Apples;Total
Bananas;Total
答案 0 :(得分:3)
尝试以下方法:
if( alldataMap.containsKey(splitter[0]) ) {
Double sum = alldataMap.remove(splitter[0]) + Double.parseDouble(splitter[8]);
allDataMap.put(splitter[0], sum );
} else {
alldataMap.put(splitter[0], Double.valueOf(splitter[8]) );
}
答案 1 :(得分:2)
自Java 8以来,您可以使用putIfAbsent
和compute
:
Map<String, Integer> myMap = new HashMap<>();
//...
String fruitName = /*whatever*/;
int qty = /*whatever*/;
myMap.putIfAbsent(fruitName, 0);
myMap.compute(fruitName, (k, oldQty) -> oldQty + qty);
答案 2 :(得分:1)
您可以使用Map#containsKey()
检查现有映射,然后是否有一个使用Map#get()
来检索值并添加新值,最后Map#put()
来存储总和:
if(map.containsKey(key))
map.put(key, map.get(key)+value);
else
map.put(key, value);
有关这些方法的文档,请参阅here。
答案 3 :(得分:1)
我会将merge
用于地图:
alldataMap.merge(splitter[0], Double.valueOf(splitter[8]), (oldVal, newVal) -> oldVal + newVal);
来自doc:
如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。否则,将相关值替换为给定重映射函数的结果,或者如果结果为null则删除。当组合密钥的多个映射值时,该方法可以是有用的。例如,要创建或附加String msg到值映射:
答案 4 :(得分:1)
我不会在循环中建议它的方式,因为已经完成了,但我建议使用唯一Streams解决方案>行:
Map<String, Double> alldataMap = new HashMap<>();
try {
alldataMap =
Files.lines(Paths.get("", filepath))
.map(str -> str.split(cvsSplitBy))
.filter(splitte -> !splitte[0].equals("Voertuig"))
.collect(Collectors.toMap(sp -> sp[0],
sp -> Double.parseDouble(sp[8].replaceAll(",", ".")),
(i1, i2) -> i1 + i2));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(alldataMap); // {Apples=4212.0, Bananas=985.23}
步骤相同:
cvsSplitBy
Voertuig
开头的行(!使用.equals()
而不是!=
)String
String
解析为Double
.getOrDefault()
编辑,因为没有人建议使用while ((line = br.readLine()) != null) {
String[] splitter = line.split(cvsSplitBy);
if (!splitter[0].equals("Voertuig")) {
alldataMap.put(splitter[0],
alldataMap.getOrDefault(splitter[0], 0.0) +
Double.parseDouble(splitter[8].replaceAll(",", ".")));
}
}
我给它
window.location.href
如果tke键已经存在,那么它总和,它的密钥不存在它会将值与0相加