通过Map <string,atomicinteger =“”> </string,>计算String []中String的出现次数

时间:2013-11-13 00:41:33

标签: java map linkedhashmap

以下方法应该计算给定集合中每个项目的出现次数:

void groupBy(String[] stuff)  {
LinkedHashMap<String, AtomicInteger> A = new LinkedHashMap<String, AtomicInteger>();

final AtomicInteger one = new AtomicInteger(1);
AtomicInteger count;

for (String key:stuff)  {
    count = A.get(key);
    if (count==null) A.put(key, one);
        else System.out.println("Previous value  :"+A.put(key, new AtomicInteger(count.incrementAndGet())));
}

  Set set = A.entrySet();
  Iterator ii = set.iterator();

  while(ii.hasNext()) {
     Map.Entry me = (Map.Entry)ii.next();
     System.out.print(me.getKey() + ": ");
     System.out.println(me.getValue());
  }
}

所以,如果我在param上运行它

String a[] = {"AAA", "A", "AA", "B", "A", "AAA"};

我应该得到

Previous value :1
Previous value :1
AAA: 2
A: 2
AA: 1
B: 1

但是,我得到的是

Previous value :2
Previous value :3
AAA: 3
A: 2
AA: 3
B: 3

散列中的值更新超出我打算做的,我不知道如何。

帮助表示赞赏。

2 个答案:

答案 0 :(得分:2)

您似乎意外地使用不同的密钥重复使用相同的AtomicInteger值。当您将AtomicInteger放入地图时,可以在致电get时重复使用。

这是发生了什么:

输入:AAA

它尚不存在,因此one被放置在地图中。

输入:A

它尚不存在,因此one放置在地图中。现在,地图中有one的两个引用。

输入:AA

它尚不存在,因此one放置在地图中。现在,地图中有one的三个引用。

输入:B

它尚不存在,因此one放置在地图中。现在,地图中有one的四个引用。

输入:A

A已存在,因此会检索该值。现在count引用与one相同的对象! count会递增,但会复制一份。现在AAAAAB仍然映射到原始AtomicInteger,但它现在已经错了;它是2。但是,A引用了第二个AtomicInteger,这在2是正确的。

输入:AAA

AAA已存在,因此会检索该值。现在count再次引用与one相同的对象! count会递增,但会复制一份。现在,AAB仍然映射到原始AtomicInteger,但它现在已经错了;它是3。但是,A仍指向第二个AtomicInteger,并且2仍然正确。此外,AAA指的是第三个AtomicInteger,但3仍然存在错误。

<强>解决方案

创建新AtomicInteger对象时更改,只需在不需要新对象时递增;他们是可变的。

for (String key : stuff)  {
    AtomicInteger count = A.get(key);
    if (count == null)
        A.put(key, new AtomicInteger(1));
    else
        count.incrementAndGet();  // Modifies the object referred to in the map.
}

答案 1 :(得分:0)

您在A.put(key, one);将问题更改为A.put(key, new AtomicInteger(1));时遇到问题,这将有效

另外,在AtomicInteger中确实没有意义,你可以将代码重写为:

LinkedHashMap<String, Long> A = new LinkedHashMap<String, Long>(stuff.length);
for (String key: stuff)
    A.put(key, (A.containsKey(key)?A.get(key):0L)+1L);