java HashMap : 添加具有公共键的值并打印出来
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14782163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HashMap : Adding values with common keys and printing them out
提问by Rachel
I have file which has String in the form key/value
pair like people and count, example would be
我有一个文件,它在表单key/value
对中包含字符串,例如人和计数,示例是
"Reggy, 15"
"Jenny, 20"
"Reggy, 4"
"Jenny, 5"
and in the output I should have summed up all count values based on key so for our example output would be
在输出中,我应该根据键总结所有计数值,因此对于我们的示例输出将是
"Reggy, 19" "Jenny, 25"
“雷吉,19 岁”“珍妮,25 岁”
Here is my approach:
这是我的方法:
- Read each line and for each line get key and count using scanner and having
,
as delimiter - Now see if key is already present before if then just add currentValues to previousValues if not then take currentValue as value of HashMap.
- 使用扫描仪读取每一行并为每一行获取键和计数并
,
作为分隔符 - 现在查看 key 之前是否已经存在 if 然后将 currentValues 添加到 previousValues 如果没有然后将 currentValue 作为 HashMap 的值。
Sample Implementation:
示例实现:
public static void main(final String[] argv) {
final File file = new File("C:\Users\rachel\Desktop\keyCount.txt");
try {
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
if (scanner.hasNext(".*,")) {
String key;
final String value;
key = scanner.next(".*,").trim();
if (!(scanner.hasNext())) {
// pick a better exception to throw
throw new Error("Missing value for key: " + key);
}
key = key.substring(0, key.length() - 1);
value = scanner.next();
System.out.println("key = " + key + " value = " + value);
}
}
} catch (final FileNotFoundException ex) {
ex.printStackTrace();
}
}
Part I am not clear about is how to divide key/value pair while reading them in and creating HashMap based on that.
我不清楚的部分是如何在读取键/值对时划分键/值对并基于此创建 HashMap。
Also is the approach am suggestion an optimal one or is there a way to enhance the performance more.
此外,我建议的方法是最佳方法还是有办法进一步提高性能。
回答by dasblinkenlight
Since this is almost certainly a learning exercise, I'll stay away from writing code, letting you have all the fun.
由于这几乎可以肯定是一项学习练习,因此我将远离编写代码,让您享受所有乐趣。
Create a HashMap<String,Integer>
. Every time that you see a key/value pair, check if the hash map has a value for the key (use 'containsKey(key)'). If it does, get that old value using get(key)
, add the new value, and store the result back using put(key, newValue)
. If the key is not there yet, add a new one - again, using put
. Don't forget to make an int
out if the String value
(use Integer.valueOf(value)
for that).
创建一个HashMap<String,Integer>
. 每次看到键/值对时,检查哈希映射是否具有键值(使用“containsKey(key)”)。如果是,则使用 获取旧值get(key)
,添加新值,然后使用 将结果存回put(key, newValue)
。如果密钥尚不存在,请添加一个新密钥 - 再次使用put
. int
如果String value
(Integer.valueOf(value)
用于那个),请不要忘记做出来。
As far as optimizing goes, any optimization at this point would be premature: it does not even work! However, it's hard to get much faster than a single loop that you have, which is also rather straightforward.
就优化而言,此时的任何优化都为时过早:它甚至不起作用!但是,很难比您拥有的单个循环快得多,这也相当简单。
回答by Aurand
For reading in, personally, I'd use:
对于个人阅读,我会使用:
Scanner.nextLine()
, String.split(",")
, and Integer.valueOf(value)
Scanner.nextLine()
, String.split(",")
, 和Integer.valueOf(value)
回答by ogzd
Try this:
试试这个:
Map<String, Long> map = new HashMap<String, Long>();
while (scanner.hasNextLine()) {
if (scanner.hasNext(".*,")) {
....
if(map.containsKey(key))
map.put(key, map.get(key) + Long.valueOf(value));
else
map.put(key, Long.valueOf(value));
}
}
回答by Sednus
Simplest way I can think about splitting the values:
我可以考虑拆分值的最简单方法:
BufferedReader reader = new BufferedReader(new FileReader(file));
Map<String, Integer> mapping = new HashMap<String,Integer>();
String currentLine;
while ((currentLine = reader.readLine()) != null) {
String[] pair = currentLine.split(",");
if(pair.length != 2){ //could be less strict
throw new DataFormatException();
}
key = pair[0];
value = Integer.parseInt(pair[1]);
if(map.contains(key)){
value += map.get(key);
}
map.put(key,value);
}
It is most likely not the most efficient way in terms of performance, but is pretty straightforward. Scanner
is usually used for parsing, but the parsing here doesn't look as complex, is just a split of strings.
就性能而言,这很可能不是最有效的方式,但非常简单。Scanner
通常用于解析,但这里的解析看起来并不复杂,只是字符串的拆分。
回答by Ritesh Karwa
Kind of late but clean solution with time complexity of O(n). This solution bypasses sort of arrays
一种时间复杂度为 O(n) 的迟到但干净的解决方案。这个解决方案绕过了一些数组
public class Solution {
public static void main(String[] args) {
// Anagram
String str1 = "School master";
String str2 = "The classroom";
char strChar1[] = str1.replaceAll("[\s]", "").toLowerCase().toCharArray();
char strChar2[] = str2.replaceAll("[\s]", "").toLowerCase().toCharArray();
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (char c : strChar1) {
if(map.containsKey(c)){
int value=map.get(c)+1;
map.put(c, value);
}else{
map.put(c, 1);
}
}
for (char c : strChar2) {
if(map.containsKey(c)){
int value=map.get(c)-1;
map.put(c, value);
}else{
map.put(c, 1);
}
}
for (char c : map.keySet()) {
if (map.get(c) != 0) {
System.out.println("Not anagram");
}
}
System.out.println("Is anagram");
}
}
回答by Jhutan Debnath
public Map<String, Integer> mergeMaps(@NonNull final Map<String, Integer> mapOne,
@NonNull final Map<String, Integer> mapTwo) {
return Stream.of(mapOne.entrySet(), mapTwo.entrySet())
.flatMap(Collection::stream)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::sum));
}