计算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()); } 

您不必使用我上面使用的两个“不同”类, ConcurrentMapAtomicInteger 。 使用它们更容易,因为它们封装了您自己尝试编写的大部分逻辑(并且失败了)。 它们封装的逻辑恰好是所有其他答案描述的(即,测试是否存在该值,如果未将其设置为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); } }