在ArrayList中计算单词出现的次数

18

我有一个包含重复词条的ArrayList

我想要对每个单词进行计数并将其存储在数据结构中。

我该如何实现?


1
排序,迭代。或者创建一个HashMap<String, int>,遍历ArrayList并每次看到字符串时将计数增加一。 - Voo
4个回答

59

如果您没有一个巨大的字符串列表,实现它的最短方式是使用Collections.frequency方法,像这样:

List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("aaa");

Set<String> unique = new HashSet<String>(list);
for (String key : unique) {
    System.out.println(key + ": " + Collections.frequency(list, key));
}

输出:

aaa: 2
bbb: 1

@Yanick,是的,但你可以将List转换为Set来知道所有唯一的单词。 - lukastymo
好的,我已经编辑了我的帖子并添加了转换。 - lukastymo
@smas:这种方法既占用内存又效率低下。 - Voo
3
@smas,查找单词频率=O(n),将列表转换为集合=O(n),从集合中查找每个单词的频率(最坏情况)=O(n); 这总共加起来是O(2(n ^ 2))。而哈希表的解决方案最多是O(2n)。 - Yanick Rochon
@Voo 我同意,这是最简单和最短的实现方法的示例。 - lukastymo
显示剩余2条评论

13

有很多可能性。一个快速实现的解决方案是使用一个Map<String,Integer>,其中String是每个单词,Integer是每个单词的计数。

遍历列表并增加该单词在地图中对应的值。如果还没有条目,则添加一个值为1的条目。

wordList = ....;

Map<String, Integer> wordCount = new HashMap<String, Integer>();

for(String word: wordList) {
  Integer count = wordCount.get(word);          
  wordCount.put(word, (count==null) ? 1 : count+1);
}

Integer 是不可变的,你需要将它放回去:wordCount.put(word, wordCount.get(word)++) - 好的,我刚刚看到你已经修复了 :) - Yanick Rochon
已经修复了,但还是谢谢你的提示 ;) - Kosi2801
我更喜欢双遍历的方法 - 在第一遍历中,只需将零放入映射表中;在第二遍历中,将值加一。这样可以避免有时令人困惑的条件逻辑,可能会稍微降低一些性能。 - Carl Manaster
在我看来,"?" 运算符是人们应该了解的东西,因为它被广泛使用。但你说得对,如果情况变得更加复杂,最好使用两遍扫描的解决方案或者使用适当的 if/else 语句,这取决于需求。 - Kosi2801
1
如果Java有一个null合并运算符(??),这看起来会更好。 - Yanick Rochon

1
这是一个测试驱动的类,可以完成您想要的功能。首先是测试:
import junit.framework.TestCase;

public class CounterTest extends TestCase {
    private Counter<String> counter;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        counter = new Counter<String>();
    }

    public void testInitialCountIsZero() throws Exception {
        assertEquals(0, counter.get("a"));
    }

    public void testCount() throws Exception {
        counter.count("a");
        assertEquals(1, counter.get("a"));
    }
}

现在是类:

import java.util.HashMap;

public class Counter<T> {
    private final HashMap<T, Integer> map = new HashMap<T, Integer>();

    public int get(T key) {
        final Integer n = map.get(key);
        return n == null ? 0 : n;
    }

    public void count(T key) {
        map.put(key, get(key) + 1);
    }
}

为了解决您的具体问题,您可以创建一个计数器,并迭代遍历您的列表,计算每个元素的数量。
Counter<String> counter = new Counter<String>();
for (String string: myList)
    counter.count(string);

0

如果你懒得自己写(或者是一个优秀的工业程序员 :p),可以使用 Google Guava 的 Multiset


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接