如何一次获取数组的索引和最大值?
How to get the index and max value of an array in one shot?
给定一个整数元素列表,如何一次获得最大值及其索引。如果有多个元素具有相同的最大值,则返回其中任何一个的索引都可以。
例如:
// Initialize list of integer
List<Integer> intList = Arrays.asList(5, 8, 3, 2);
// To get max value
Optional<Integer> maxVal = intList.stream().reduce(Integer::max);
// But how could I also get its index without iterating the array again?
如果我只需要做一次,我可以只对数组进行排序并获取第一个或最后一个(基于排序顺序)。但是,我想看看我们如何在不排序的情况下做到这一点。
通常,如果您需要索引,则必须流式处理索引。那么,任务就变得简单了:
List<Integer> intArr = Arrays.asList(5, 8, 3, 2);
IntStream.range(0, intArr.size())
.reduce((a,b)->intArr.get(a)<intArr.get(b)? b: a)
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
一个更优雅的解决方案,不幸的是包含了装箱开销
IntStream.range(0, intArr.size())
.boxed().max(Comparator.comparing(intArr::get))
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
如果您不介意使用第三方代码,我的 StreamEx 库为该任务提供了一些快捷方式:
List<Integer> intArr = Arrays.asList(5, 8, 3, 2);
IntStreamEx.ofIndices(intArr)
.maxBy(intArr::get)
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
在内部它接近@Holger 提供的第一个解决方案(无装箱)。
在java8中你可以execute streams in parallel
Integer[] intArr= {1,2,6,2,234,3,54,6,4564,456};
IntStream.range(0, intArr.length-1).parallel().
reduce((a,b)->intArr[a]<intArr[b]? b: a).
ifPresent(ix -> System.out.println("Index: " + ix + ", value: " + intArr[ix]));
我认为目前没有任何解决方案与手动迭代一样快:
int maxValueIndex = 0;
Integer maxValue = null;
for (int i = 0, n = intList.size(); i < n; ++i) {
Integer value = intList.get(i);
if (value == null || maxValue != null && value <= maxValue)
continue;
maxValue = value;
maxValueIndex = i;
}
给定一个整数元素列表,如何一次获得最大值及其索引。如果有多个元素具有相同的最大值,则返回其中任何一个的索引都可以。
例如:
// Initialize list of integer
List<Integer> intList = Arrays.asList(5, 8, 3, 2);
// To get max value
Optional<Integer> maxVal = intList.stream().reduce(Integer::max);
// But how could I also get its index without iterating the array again?
如果我只需要做一次,我可以只对数组进行排序并获取第一个或最后一个(基于排序顺序)。但是,我想看看我们如何在不排序的情况下做到这一点。
通常,如果您需要索引,则必须流式处理索引。那么,任务就变得简单了:
List<Integer> intArr = Arrays.asList(5, 8, 3, 2);
IntStream.range(0, intArr.size())
.reduce((a,b)->intArr.get(a)<intArr.get(b)? b: a)
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
一个更优雅的解决方案,不幸的是包含了装箱开销
IntStream.range(0, intArr.size())
.boxed().max(Comparator.comparing(intArr::get))
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
如果您不介意使用第三方代码,我的 StreamEx 库为该任务提供了一些快捷方式:
List<Integer> intArr = Arrays.asList(5, 8, 3, 2);
IntStreamEx.ofIndices(intArr)
.maxBy(intArr::get)
.ifPresent(ix->System.out.println("Index "+ix+", value "+intArr.get(ix)));
在内部它接近@Holger 提供的第一个解决方案(无装箱)。
在java8中你可以execute streams in parallel
Integer[] intArr= {1,2,6,2,234,3,54,6,4564,456};
IntStream.range(0, intArr.length-1).parallel().
reduce((a,b)->intArr[a]<intArr[b]? b: a).
ifPresent(ix -> System.out.println("Index: " + ix + ", value: " + intArr[ix]));
我认为目前没有任何解决方案与手动迭代一样快:
int maxValueIndex = 0;
Integer maxValue = null;
for (int i = 0, n = intList.size(); i < n; ++i) {
Integer value = intList.get(i);
if (value == null || maxValue != null && value <= maxValue)
continue;
maxValue = value;
maxValueIndex = i;
}