2015-06-09 53 views
7

给定一个整数元素列表,如何获得最大值和它的一次性索引。如果有多个具有相同最大值的元素,则返回其中任何一个元素的索引都可以。如何一次获取数组的索引和最大值?

例如:

// 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? 

如果我必须这样做只有一次,我可以排序的阵列,并获得第一个或最后一个(根据排序顺序)。但是,我想看看我们如何在不分类的情况下做到这一点。

回答

8

一般来说,如果你需要一个索引,你必须流过索引。然后,任务变得简单直接:

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))); 
+0

什么是盒装的意义是什么? –

+1

@SriniK我相信那是因为你不能有一个“Comparator ”。但是,再次,我可能是错的,因为我对Java 8还是有点新的。 – CKing

+3

@Chetan Kinger:你说得对,没有'Comparator ',因此'IntStream'不提供'max(比较器) '方法,但只有'max()'在这里没有帮助(同样适用于'min'或'sorted','IntStream'只支持自然顺序)。 – Holger

1

如果你不介意使用第三方的代码,我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提供的第一个解决方案(无装箱)。

1

在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])); 
0

我不认为有是目前唯一的手动同样以最快的速度迭代任何解决方案:

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; 
} 
相关问题