我正在编写一个项目,从.java文件中捕获Java关键字,并使用地图跟踪事件.我过去使用过类似的方法,但是我似乎无法在这里使用这种方法.
Map<String,Integer> map = new TreeMap<String,Integer>();
Set<String> keywordSet = new HashSet<String>(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);
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码应该将关键字添加到密钥中,并在每次出现相同密钥时递增值.到目前为止,它添加了关键字,但无法正确增加值.这是一个示例输出:
{assert=2, class=2, continue=2, default=2, else=2, ...}
Run Code Online (Sandbox Code Playgroud)
基本上它会增加地图中的每个值而不是它应该的值.我不确定我是否过度思考这个或者什么.我尝试了一个内循环,它给了我疯狂的结果.我真的希望我只是过度思考这个问题.任何帮助是极大的赞赏!
Bru*_*eis 11
有一种更简洁(更容易推理)的方式来实现你想要的东西:
final ConcurrentMap<String, AtomicInteger> 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();
}
}
Run Code Online (Sandbox Code Playgroud)
让我们分析一下为什么这样做.
每当Scanner遇到关键字时,有两种可能的情况:您之前遇到过它(即,它是一个已知的关键字),或者它是一个尚未看到的关键字.
putIfAbsent将AtomicInteger在地图中放置一个值为0的值,并incrementAndGet()在之后将其设置为1,并且从现在开始,它将成为一个已知的关键字 ;putIfAbsent将不执行任何操作,incrementAndGet()并将增加映射中已存在的值.然后,如果你想要密钥集,你可以:
final Set<String> keys = map.keySet();
Run Code Online (Sandbox Code Playgroud)
要打印所有值,您可以执行以下操作:
for (final String k : map.keySet()) {
System.out.println(k + ": " + map.get(k).get());
}
Run Code Online (Sandbox Code Playgroud)
你不是被迫使用我上面使用的两个"不同"类,ConcurrentMap而且AtomicInteger.使用它们更容易,因为它们封装了您自己尝试编写的大部分逻辑(并且失败了).它们封装的逻辑正是所有其他答案所描述的(即,测试是否存在该值,如果未将其设置为0,则获取存在的任何值,增加它并将其放回到映射中).
对于您扫描的每个键,您将在地图中创建一个新条目(覆盖现有条目).然后,下一个条件成立,因此您将计数增加1,达到值2.
内部应该是这样的:
if (keywordSet.contains(key))
{
Integer value = map.get(key);
if (value == null)
value = 0;
value++;
map.put(key, value);
}
Run Code Online (Sandbox Code Playgroud)
无论如何,考虑使用某种可变整数来提高效率.您不必覆盖地图中的条目,也不会进行太多的整数拳击操作.
更简洁的使用Map.merge()(自 Java 8 起):
if (keywordSet.contains(key)) {
map.merge(key, 1, (currentCount, notUsed) -> ++currentCount);
}
Run Code Online (Sandbox Code Playgroud)
这是计数映射的通用实现- 一个映射,其值表示其键的计数:
public static <K> void count(K key, Map<K, Integer> map) {
map.merge(key, 1, (currentCount, notUsed) -> ++currentCount);
}
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
count("A", map);
count("B", map);
count("A", map);
count("Z", map);
count("A", map);
System.out.println(map); // {A=3, B=1, Z=1}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22309 次 |
| 最近记录: |