Java 计算ArrayList中出现的单词数

Java 计算ArrayList中出现的单词数,java,arraylist,count,Java,Arraylist,Count,我有一个包含重复条目的单词的ArrayList 我想计算并保存数据结构中每个单词的出现次数 我该怎么做呢?如果你没有一个庞大的字符串列表,实现它的最短方法是使用Collections.frequency方法,如下所示: List<String> list = new ArrayList<String>(); list.add("aaa"); list.add("bbb"); list.add("aaa"); Set<String> unique = new

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

我想计算并保存数据结构中每个单词的出现次数


我该怎么做呢?

如果你没有一个庞大的字符串列表,实现它的最短方法是使用
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));
}

有很多可能性。一个快速实现的解决方案可以是使用
映射
,其中字符串是每个单独的单词,整数是每个单词的计数

遍历列表并在映射中为其增加相应的值。如果还没有条目,则添加一个值为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);
}
wordList=。。。。;
Map wordCount=new HashMap();
for(字符串字:单词列表){
整数计数=wordCount.get(word);
put(word,(count==null)?1:count+1;
}

或者如果你太懒了,不想自己做(或者是一个好的工业程序员:p),请使用google guava。

这里有一个测试驱动类,它可以做你想做的事情。首先是测试:

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"));
    }
}
导入junit.framework.TestCase;
公共类反测试扩展了TestCase{
私人柜台;
@凌驾
受保护的void setUp()引发异常{
super.setUp();
计数器=新计数器();
}
public void TestInitialCountszero()引发异常{
assertEquals(0,counter.get(“a”));
}
public void testCount()引发异常{
计数器计数(“a”);
资产质量(1,计数器获取(“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);
    }
}
import java.util.HashMap;
公共课柜台{
private final HashMap map=new HashMap();
公共int get(T键){
最终整数n=map.get(键);
返回n==null?0:n;
}
公共无效计数(T键){
map.put(键),get(键)+1;
}
}
为了解决您的特定问题,您需要创建一个计数器,并在列表上迭代,对每个元素进行计数

Counter<String> counter = new Counter<String>();
for (String string: myList)
    counter.count(string);
计数器计数器=新计数器();
for(字符串:myList)
计数器计数(字符串);

对其进行排序,并对其进行迭代。或者创建一个HashMap,在arraylist上迭代,每次看到字符串时增加一个计数。如果您想知道确切的单词频率,这很好,但对列表中的每个单词重复此操作…@Yanick,是的,但您可以将列表转换为Set以了解所有唯一的wordsok,我已经编辑了我的帖子并添加了conversion@smas:这种方法既占用大量内存,又效率低下。@smas,查找单词频率=O(n),将列表转换为集合=O(n),从集合中查找每个单词的频率(最坏情况)=O(n);这等于O(2(n^2))。虽然哈希表解决方案最多是O(2n)
Integer
是不可变的,但您需要将其放回:wordCount.put(word,wordCount.get(word)++)-好的,我刚才看到您已经修复了:)已经修复了,但感谢您的提示;)我更喜欢两次通过的方法——在第一次通过时,只需将零放入地图;在第二种情况下,向值中添加一个。这避免了有时令人困惑的条件逻辑,但(可能)付出了一些轻微的性能代价。在我看来,“?”运算符是人们应该注意的,因为它被广泛使用。但是你是对的,如果它会变得更复杂,那么最好使用两次通过的解决方案,或者使用适当的if/else,这取决于需求。如果Java有一个空合并操作符(??),这看起来会更好
Counter<String> counter = new Counter<String>();
for (String string: myList)
    counter.count(string);