这是一个纯 Java 8 解决方案(注意:不要使用这个,见下文):
List<Integer> theList = Arrays.asList(1, 3, 4, 3, 4, 3, 2, 3, 3, 3, 3, 3);
Integer maxOccurredElement = theList.stream()
.reduce(BinaryOperator.maxBy((o1, o2) -> Collections.frequency(theList, o1) -
Collections.frequency(theList, o2))).orElse(null);
System.out.println(maxOccurredElement);
另一种解决方案,通过按频率将元素收集到地图中,然后找到具有最大值的条目并返回其键(与arshajii's answer 上的解决方案基本相同,使用 Java 8 编写):
Integer maxVal = theList.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream().max((o1, o2) -> o1.getValue().compareTo(o2.getValue()))
.map(Map.Entry::getKey).orElse(null);
更新:如果最频繁的元素不止一个,并且你想将它们全部放在一个集合中,我提出两种方法:
方法A: 将原始集合收集到一个以键为元素、值为出现次数的映射后,获取最大值的条目并过滤与此值相等的映射条目我们找到的最大值(如果)。像这样的:
Map<Integer, Long> elementCountMap = theList.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<Integer> result = elementCountMap.values().stream()
.max(Long::compareTo).map(maxValue -> elementCountMap.entrySet().stream()
.filter(entry -> maxValue.equals(entry.getValue())).map(Map.Entry::getKey).collect(Collectors.toList()))
.orElse(Collections.emptyList());
方法B:将原始集合收集到一个以key为元素,value为出现次数的map后,将这个map转换为以key为出现次数,value为出现次数的新map具有此出现次数的元素列表。然后使用比较键的自定义比较器找到此映射的最大元素,并获取此条目的值。像这样:
List<Integer> result = theList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
.entrySet().stream().max((o1, o2) -> o1.getKey().compareTo(o2.getKey())).map(Map.Entry::getValue)
.orElse(Collections.emptyList());