如何在 Java 的列表中找到所有最大值?
How to find ALL maximum values in a List in Java?
我有一个存储不同数字的列表,其中最大的是索引下的元素:2; 4.
我想将这 2 个元素打印到控制台 - 作为数组中的最大数字,但是 Collections.max () 方法 returns 只有它找到的第一个最大值,即,只有索引 2 处的元素:
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
System.out.println(Collections.max(numbers));
|Output|
50
我应该使用什么代替方法 Collections.max() 来查找所有最大值?
这使用一次迭代来找到它们
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
int max = Integer.MIN_VALUE;
int count = 1;
for(int number : numbers){
if(number > max){
max = number;
count = 1;
} else if(number == max){
count++;
}
}
for(int i=0; i<count; i++){
System.out.println(max);
}
默认情况下没有给定函数执行此操作。所以你可以做的是根据给定的值过滤这个列表。这将导致 2 次迭代,但代码简单。如果您在自己的循环中执行此操作,则代码更多但效率更高。
根据数据量,您应该选择高效方式或可读方式。
// 2 iterations - 1st for finding max , 2nd for filter
int maxValue = Collections.max(numbers);
List<Integer> maxValues = numbers.stream().filter(number -> number == max).collect(Collectors.toList()); // only need size? Add .size() at the end
// efficient - just 1 iteration, but not pretty to read.
int currentMax = numbers[0];
int counter = 0;
for(Integer number in numbers) {
if(currentMax == number) {
counter++;
} else if(currentMax < number) {
counter = 1;
currentMax = number;
}
}
您可以先遍历列表以找到最大值,然后再次循环列表以将最大值及其索引放入地图。
Map map = new HashMap();
int curMax = 0;
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i)>=curMax){
curMax = numbers.get(i);
}
}
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) == curMax){
map.put(i, numbers.get(i));
}
}
System.out.println(map.toString());
输出:
{2=50, 4=50}
max
将始终找到最大值而不是出现次数。你想要的总是需要分两步完成。
// If you start from a List
List<Integer> numbers = Arrays.asList(5, 9, 50, 12, 50);
IntSummaryStatistics numberStats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
// But you can also start from the stream itself
IntSummaryStatistics numberStats = IntStream.of(5, 9, 50, 12, 50).summaryStatistics();
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
/*
* You can also use the plain max number instead of the summaryStatistics, which is
* more performant but the stream cannot be reuse for e.g. min or average.
* Note here we use equals because we don't use primitive int but Object Integer as it's not an IntSteam
*/
Integer maxInt = numbers.stream().max(Comparator.naturalOrder()).orElseThrow();
numbers.stream().filter(number -> number.equals(maxInt)).forEach(System.out::println);
Comparator.naturalOrder()
意味着您不提供比较器,但让 Java 使用它的默认比较器,它对所有基元、盒装基元和字符串都有。对单词和数字进行排序是众所周知的自然事情,不需要任何实现。
您可以先找到 maximal elements by lifting 整数值到列表中,然后减少该列表:
List<Integer> max = numbers.stream()
.collect(Collectors.reducing(
Collections.singletonList(Integer.MIN_VALUE),
Collections::singletonList,
(l1, l2) -> {
if (l1.get(0) > l2.get(0)) {
return l1;
} else if (l2.get(0) > l1.get(0)) {
return l2;
} else {
List<Integer> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}
}));
我有一个存储不同数字的列表,其中最大的是索引下的元素:2; 4.
我想将这 2 个元素打印到控制台 - 作为数组中的最大数字,但是 Collections.max () 方法 returns 只有它找到的第一个最大值,即,只有索引 2 处的元素:
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
System.out.println(Collections.max(numbers));
|Output|
50
我应该使用什么代替方法 Collections.max() 来查找所有最大值?
这使用一次迭代来找到它们
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(5);
numbers.add(9);
numbers.add(50);
numbers.add(12);
numbers.add(50);
int max = Integer.MIN_VALUE;
int count = 1;
for(int number : numbers){
if(number > max){
max = number;
count = 1;
} else if(number == max){
count++;
}
}
for(int i=0; i<count; i++){
System.out.println(max);
}
默认情况下没有给定函数执行此操作。所以你可以做的是根据给定的值过滤这个列表。这将导致 2 次迭代,但代码简单。如果您在自己的循环中执行此操作,则代码更多但效率更高。
根据数据量,您应该选择高效方式或可读方式。
// 2 iterations - 1st for finding max , 2nd for filter
int maxValue = Collections.max(numbers);
List<Integer> maxValues = numbers.stream().filter(number -> number == max).collect(Collectors.toList()); // only need size? Add .size() at the end
// efficient - just 1 iteration, but not pretty to read.
int currentMax = numbers[0];
int counter = 0;
for(Integer number in numbers) {
if(currentMax == number) {
counter++;
} else if(currentMax < number) {
counter = 1;
currentMax = number;
}
}
您可以先遍历列表以找到最大值,然后再次循环列表以将最大值及其索引放入地图。
Map map = new HashMap();
int curMax = 0;
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i)>=curMax){
curMax = numbers.get(i);
}
}
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) == curMax){
map.put(i, numbers.get(i));
}
}
System.out.println(map.toString());
输出:
{2=50, 4=50}
max
将始终找到最大值而不是出现次数。你想要的总是需要分两步完成。
// If you start from a List
List<Integer> numbers = Arrays.asList(5, 9, 50, 12, 50);
IntSummaryStatistics numberStats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
// But you can also start from the stream itself
IntSummaryStatistics numberStats = IntStream.of(5, 9, 50, 12, 50).summaryStatistics();
numbers.stream().filter(number -> number == numberStats.getMax()).forEach(System.out::println);
/*
* You can also use the plain max number instead of the summaryStatistics, which is
* more performant but the stream cannot be reuse for e.g. min or average.
* Note here we use equals because we don't use primitive int but Object Integer as it's not an IntSteam
*/
Integer maxInt = numbers.stream().max(Comparator.naturalOrder()).orElseThrow();
numbers.stream().filter(number -> number.equals(maxInt)).forEach(System.out::println);
Comparator.naturalOrder()
意味着您不提供比较器,但让 Java 使用它的默认比较器,它对所有基元、盒装基元和字符串都有。对单词和数字进行排序是众所周知的自然事情,不需要任何实现。
您可以先找到 maximal elements by lifting 整数值到列表中,然后减少该列表:
List<Integer> max = numbers.stream()
.collect(Collectors.reducing(
Collections.singletonList(Integer.MIN_VALUE),
Collections::singletonList,
(l1, l2) -> {
if (l1.get(0) > l2.get(0)) {
return l1;
} else if (l2.get(0) > l1.get(0)) {
return l2;
} else {
List<Integer> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}
}));