计算Java中Map的键的出现次数
我正在编写一个项目,从.java文件中捕获Java关键字,并使用地图跟踪事件。 我过去使用过类似的方法,但是我似乎无法在这里采用这种方法。
Map map = new TreeMap(); Set keywordSet = new HashSet(Arrays.asList(keywords)); Scanner input = new Scanner(file); int counter = 0; while (input.hasNext()) { String key = input.next(); if (key.length() > 0) { if (keywordSet.contains(key)) { map.put(key, 1); counter++; } if(map.containsKey(key)) <--tried inner loop here, failed { int value = map.get(key); value++; map.put(key, value); } }
这段代码应该将关键字添加到密钥中,并在每次出现相同密钥时递增值。 到目前为止,它添加了关键字,但无法正确增加值。 这是一个示例输出:
{assert=2, class=2, continue=2, default=2, else=2, ...}
基本上它会增加地图中的每个值而不是它应该的值。 我不确定我是否过度思考这个或者什么。 我尝试了一个内循环,它给了我疯狂的结果。 我真的希望我只是过度思考这个问题。 任何帮助是极大的赞赏!
对于您扫描的每个键,您将在地图中创建一个新条目(覆盖现有条目)。 然后,下一个条件成立,因此您将计数增加1,达到值2。
内部应该是这样的:
if (keywordSet.contains(key)) { Integer value = map.get(key); if (value == null) value = 0; value++; map.put(key, value); }
无论如何,考虑使用某种可变整数来提高效率。 您不必覆盖地图中的条目,也不会进行太多的整数拳击操作。
有一种更简洁(更容易推理)的方式来实现你想要的东西:
final ConcurrentMap map = new ConcurrentHashMap<>(); final Scanner input = new Scanner(file); while (input.hasNext()) { final String key = input.next(); if (key.length() > 0) { map.putIfAbsent(key, new AtomicInteger(0)); map.get(key).incrementAndGet(); } }
让我们分析一下为什么这样做。
每当Scanner
遇到关键字时,有两种可能的情况:您之前遇到过它(即,它是一个已知的关键字 ),或者它是一个尚未看到的关键字 。
- 如果它是一个看不见的关键字 :
putIfAbsent
会在地图中放置一个值为0的AtomicInteger
,而incrementAndGet()
会在之后将其设置为1,并且从现在开始,它将成为一个已知的关键字 ; - 如果它是一个已知关键字 :
putIfAbsent
将不执行任何操作,incrementAndGet()
将递增已存在于地图中的值。
然后,如果你想要密钥集,你可以:
final Set keys = map.keySet();
要打印所有值,您可以执行以下操作:
for (final String k : map.keySet()) { System.out.println(k + ": " + map.get(k).get()); }
您不必使用我上面使用的两个“不同”类, ConcurrentMap
和AtomicInteger
。 使用它们更容易,因为它们封装了您自己尝试编写的大部分逻辑(并且失败了)。 它们封装的逻辑恰好是所有其他答案描述的(即,测试是否存在该值,如果未将其设置为0,则获取存在的任何值,将其递增并将其重新放回到映射中)。
您始终将值设置为1,然后再将其更新为1。 您需要的是更新地图值(而不是再次将其设置为1)。
代替:
map.put(key, 1);
使用:
Integer value = map.get(key); if (value == null){ value = 0 } value++; map.put(key, value);
并删除第二个if。
使用Map.merge()
(Java 8)更简洁:
if (keywordSet.contains(key)) { map.merge(key, 1, (v, vv) -> ++v); }
Map map = new HashMap(); Set keywordSet = new HashSet (Arrays.asList(keywords)); Scanner input = new Scanner(file); while (input.hasNext()){ String key = input.next(); if (key.length() > 0) if (keywordSet.contains(key)){ Integer counter = map.get(key); if (counter == null) map.put(key, 1); else map.put(key, count + 1); } }