2015-06-09 91 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; 
} 
相關問題