有办法在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。
然后有一个具有所有唯一String
的HashMap
,以及一个说明其在数组中数量的相关数字。
如果有人需要从常用的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;
}
}
应该这样做。