我有两个结构如下的类:
public class Company {
private List<Person> person;
...
public List<Person> getPerson() {
return person;
}
...
}
public class Person {
private String tag;
...
public String getTag() {
return tag;
}
...
}
基本上,Company类有一个Person对象列表,每个Person对象都可以获得Tag值。
如果我得到Person对象的List,是否有办法使用Java 8中的Stream来查找所有Person对象中最常见的一个Tag值(如果是平局,可能只是随机最常见的)?
String mostCommonTag;
if(!company.getPerson().isEmpty) {
mostCommonTag = company.getPerson().stream() //How to do this in Stream?
}
答案 0 :(得分:24)
String mostCommonTag = getPerson().stream()
// filter some person without a tag out
.filter(it -> Objects.nonNull(it.getTag()))
// summarize tags
.collect(Collectors.groupingBy(Person::getTag, Collectors.counting()))
// fetch the max entry
.entrySet().stream().max(Map.Entry.comparingByValue())
// map to tag
.map(Map.Entry::getKey).orElse(null);
AND getTag
方法出现两次,您可以进一步简化代码:
String mostCommonTag = getPerson().stream()
// map person to tag & filter null tag out
.map(Person::getTag).filter(Objects::nonNull)
// summarize tags
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
// fetch the max entry
.entrySet().stream().max(Map.Entry.comparingByValue())
// map to tag
.map(Map.Entry::getKey).orElse(null);
答案 1 :(得分:5)
这应该适合你:
commonness
mostCommon
地图包含经常找到哪个标记的信息。变量mostCommon
包含最常找到的标记。此外,如果原始列表为空,则Map<String, Long> count = persons.stream().collect(
Collectors.groupingBy(Person::getTag, Collectors.counting()));
Optional<Entry<String, Long>> maxValue = count .entrySet()
.stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();
maxValue.get().getValue();
为空。
答案 2 :(得分:5)
您可以将计数收集到Map,然后获取具有最高值的键
List<String> foo = Arrays.asList("a","b","c","d","e","e","e","f","f","f","g");
Map<String, Long> f = foo
.stream()
.collect(Collectors.groupingBy(v -> v, Collectors.counting()));
String maxOccurence =
Collections.max(f.entrySet(), Comparator.comparing(Map.Entry::getValue)).getKey();
System.out.println(maxOccurence);
答案 3 :(得分:5)
如果您愿意使用第三方库,则可以使用Collectors2
中的Eclipse Collections与Java 8 class Boy(Person):
def __init__(self, first_name, last_name, height):
super(Person, self).__init__(first_name, last_name)
self.height = height
创建Stream
并请求{ {1}},它将返回Bag
topOccurrences
,这是标记值和出现次数的计数。
MutableList
如果是平局,ObjectIntPair
将有多个结果。
注意:我是Eclipse Collections的提交者。
答案 4 :(得分:3)
这对你有帮助,
Expire
答案 5 :(得分:3)
// Comparing the solution by jdk stream,
// there is no "collect(Collectors.groupingBy(Person::getTag, Collectors.counting())).entrySet().stream"
Stream.of(company.getPerson()).map(Person::getTag).skipNull() //
.groupBy(Fn.identity(), Collectors.counting()) //
.max(Comparators.comparingByValue()).map(e -> e.getKey()).orNull();
// Or by multiset
Stream.of(company.getPerson()).map(Person::getTag).skipNull() //
.toMultiset().maxOccurrences().map(e -> e.getKey()).orNull();