在ArrayList()中找到最常见的字符串

13

有没有一种方法可以找到 ArrayList 中最常见的 String

ArrayList<String> list = new ArrayList<>();
list.add("test");
list.add("test");
list.add("hello");
list.add("test");

从这个列表["test","test","hello","test"]中查找单词"test"


9
有一种方法,但是没有直接的方式。您需要编写一些代码来实现。 - Rohit Jain
是的,你必须使用Map,例如HashMap。 - ruhungry
这个回答解决了你的问题吗?Java-获取列表中最常见的元素 - Jacob van Lingen
12个回答

16

不要重复造轮子,使用Collections类的frequency方法:

public static int frequency(Collection<?> c, Object o)
返回指定集合中等于指定对象的元素数量。更正式地说,返回集合中满足(o == null ? e == null : o.equals(e))的元素e的数量。 如果您需要计算所有元素的出现次数,请使用Map和巧妙地循环或将列表放入Set并在集合的每个元素上使用上面的frequency方法。HTH 编辑/Java 8: 如果您喜欢具有lambda表达式的更功能性的Java 8单行解决方案,请尝试:
Map<String, Long> occurrences = 
  list.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting()));

1
使用Function.identity()代替w->w - Cemo
这段代码并不返回每个字符串中每个单词的频率,而是返回最常出现的字符串。我该如何修改代码以返回出现在一个字符串列表中的单词的频率最高的那些单词呢? - Metin Dagcilar
@Cemo,我个人认为在一种更加简洁的语言中,w -> w 更不啰嗦。有什么支持使用 Function.identity() 的强有力的论据吗? - VH-NZZ

11

在统计学中,这被称为“众数(mode)”一个标准的Java 8解决方案看起来像这样:

Stream.of("test","test","hello","test")
      .collect(Collectors.groupingBy(s -> s, Collectors.counting()))
      .entrySet()
      .stream()
      .max(Comparator.comparing(Entry::getValue))
      .ifPresent(System.out::println);

导致结果为:

test=3

jOOλ是一个支持在流上使用mode()方法的库。以下程序:

System.out.println(
    Seq.of("test","test","hello","test")
       .mode()
);

产生:

Optional[test]

(免责声明:本人为jOOλ背后公司的员工)


9
根据问题,具体只是获取单词,而不是次数(即键的值)。
String mostRepeatedWord 
    = list.stream()
          .collect(Collectors.groupingBy(w -> w, Collectors.counting()))
          .entrySet()
          .stream()
          .max(Comparator.comparing(Entry::getValue))
          .get()
          .getKey();

6
您可以创建一个 HashMap<String,Integer>。如果字符串已经在Map中出现过,则将其 的值加一,否则将其添加到Map中。
例如:
put("someValue", 1);

那么,假设它再次是“someValue”,你可以这样做:
put("someValue", get("someValue") + 1);

由于“someValue”的键是1,现在当您放置它时,键将变为2。

之后,您可以轻松地遍历映射并提取具有最高价值的键。

我没有编写完整的解决方案,如果您有问题,请在另一个问题中发布。最佳实践是自学。


使用yourMap.compute("someValue", (k, counter) -> counter == null ? 0 : counter + 1)向地图中插入数据! - Jacob van Lingen

2
我认为最好的方法是使用包含计数的地图。
Map<String, Integer> stringsCount = new HashMap<>();

遍历你的数组,填充这个映射表:

for(String s: list)
{
  Integer c = stringsCount.get(s);
  if(c == null) c = new Integer(0);
  c++;
  stringsCount.put(s,c);
}

最后,您可以通过遍历Map来获取最重复的元素:
Map.Entry<String,Integer> mostRepeated = null;
for(Map.Entry<String, Integer> e: stringsCount.entrySet())
{
    if(mostRepeated == null || mostRepeated.getValue()<e.getValue())
        mostRepeated = e;
}

并显示最常见的字符串:

if(mostRepeated != null)
        System.out.println("Most common string: " + mostRepeated.getKey());

0

如果有人需要在通常的String[]数组中找到最受欢迎的(使用列表):

public String findPopular (String[] array) {
    List<String> list = Arrays.asList(array);
    Map<String, Integer> stringsCount = new HashMap<String, Integer>();
    for(String string: list)
    {
        if (string.length() > 0) {
            string = string.toLowerCase();
            Integer count = stringsCount.get(string);
            if(count == null) count = new Integer(0);
            count++;
            stringsCount.put(string,count);
        }
    }
    Map.Entry<String,Integer> mostRepeated = null;
    for(Map.Entry<String, Integer> e: stringsCount.entrySet())
    {
        if(mostRepeated == null || mostRepeated.getValue()<e.getValue())
            mostRepeated = e;
    }
    try {
        return mostRepeated.getKey();
    } catch (NullPointerException e) {
        System.out.println("Cannot find most popular value at the List. Maybe all strings are empty");
        return "";
    }

}
  • 不区分大小写的情况

0
你可以使用Guava的Multiset:
ArrayList<String> names = ...

// count names 
HashMultiset<String> namesCounts = HashMultiset.create(names);
Set<Multiset.Entry<String>> namesAndCounts = namesCounts.entrySet();

// find one most common
Multiset.Entry<String> maxNameByCount = Collections.max(namesAndCounts, Comparator.comparing(Multiset.Entry::getCount));

// pick all with the same number of occurrences
List<String> mostCommonNames = new ArrayList<>();
for (Multiset.Entry<String> nameAndCount : namesAndCounts) {
    if (nameAndCount.getCount() == maxNameByCount.getCount()) {
        mostCommonNames.add(nameAndCount.getElement());
    }
}

0
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

公共类StringChecker {

public static void main(String[] args) {
ArrayList<String> string;
string = new ArrayList<>(Arrays.asList("Mah", "Bob", "mah", "bat", "MAh", "BOb"));
Map<String, Integer> wordMap = new HashMap<String, Integer>();

for (String st : string) {
    String input = st.toUpperCase();
    if (wordMap.get(input) != null) {
        Integer count = wordMap.get(input) + 1;
        wordMap.put(input, count);
    } else {
        wordMap.put(input, 1);
    }
}
System.out.println(wordMap);
Object maxEntry = Collections.max(wordMap.entrySet(), Map.Entry.comparingByValue()).getKey();
System.out.println("maxEntry = " + maxEntry);

}


0
使用这种方法,如果您的ArrayList中有多个最常见元素,则通过将它们添加到新的ArrayList中,您可以获得它们所有的返回值。
public static void main(String[] args) {

 List <String> words = new ArrayList<>() ; 

words.add("cat") ; 
words.add("dog") ; 
words.add("egg") ; 
words.add("chair") ; 
words.add("chair") ; 
words.add("chair") ; 
words.add("dog") ; 
words.add("dog") ;  

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

    for (String word : words) {  /* Counts the quantity of each 
                                      element */
        if (! count.containsKey(word)) {             
            count.put(word, 1 ) ; 
        }

        else {
            int value = count.get(word) ; 
            value++ ; 

            count.put(word, value) ;
        }       
    }

    List <String> mostCommons = new ArrayList<>() ; /* Max elements  */

    for ( Map.Entry<String,Integer> e : count.entrySet() ) {

        if (e.getValue() == Collections.max(count.values() )){
                            /* The max value of count  */

            mostCommons.add(e.getKey()) ;
        }   
    }

    System.out.println(mostCommons);

 }

}

0
你可以使用一个 HashMap<String,Integer>。遍历数组,对于每个 String,如果它还不是你的 HashMap 的键,则将其添加并将值设置为 1;如果它已经是键,则将其值增加 1。
然后你就有了一个包含所有唯一的 String 和与之关联的数字(表示它们在数组中出现的次数)的 HashMap

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