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



有办法在ArrayList中找到最常见的String吗?

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

应在此列表中找到单词"test"["test","test","hello","test"]

不要重新发明轮子并使用Collections类的frequency方法:

public static int frequency(Collection<?> c, Object o)

返回指定集合中等于的元素数指定的对象。更正式地说,返回元素的数量e在集合中,使得(o==null?e==null:o.equals(e)).

如果您需要计数所有元素的出现次数,请巧妙地使用Map和循环:)或者将您的列表放在一个集合中,并使用上面的frequency方法对集合中的每个元素进行循环。HTH-

EDIT/Java 8:如果您想要一个功能更强大的、带有lambdas的Java 8单行解决方案,请尝试:

Map<String, Long> occurrences = 
  list.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting()));

在统计学中,这被称为"模式"。一个普通的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λ背后的公司工作)

根据问题,具体来说只是获取单词,而不是次数(即键的值)。

String mostRepeatedWord 
    = list.stream()
          .collect(Collectors.groupingBy(w -> w, Collectors.counting()))
          .entrySet()
          .stream()
          .max(Comparator.comparing(Entry::getValue))
          .get()
          .getKey();

您可以制作HashMap<String,Integer>。如果字符串已经出现在映射中,则将其增加一,否则,将其添加到映射中。

例如:

put("someValue", 1);

然后,假设它再次是"someValue",你可以这样做:

put("someValue", get("someValue") + 1);

由于"someValue"的是1,现在当你放它时,键将是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.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());

您可以使用HashMap<String,Integer>。在数组中循环,如果每个String还不是HashMap的Key,则可以检查它,将其相加并将值设置为1,如果是,则将其值增加1。

然后有一个具有所有唯一StringHashMap,以及一个说明其在数组中数量的相关数字。

如果有人需要从常用的String[]数组中找到最流行的字符串(使用Lists):

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 "";
    }
}
  • 大小写不敏感

我知道这需要更多的时间来实现,但您可以通过在节点中存储计数和字符串信息

来使用堆数据结构

您可以使用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());
    }
}
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);

}

使用此方法,如果您的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);
 }
}

有很多答案建议使用HashMaps。我真的不喜欢它们,因为无论如何你都必须再次迭代它们。相反,我会对列表进行排序

Collections.sort(list);

然后循环通过。类似的东西

String prev = null, mostCommon=null;
int num = 0, max = 0;
for (String str:list) {
  if (str.equals(prev)) {
    num++;
  } else {
    if (num>max) {
      max = num;
      mostCommon = str;
    }
    num = 1;
    prev = str;
  }
}

应该这样做。

最新更新