我想獲取 min 的索引,我嘗試了 getIndexOf 等方法,但都沒有用。我怎樣才能做到這一點?
import java.util.Arrays;
class getIndexOfMin {
public static void main(String[] args) {
double arr[] = {263.5, 393.75, 5.0, 289.75};
double min = Arrays.stream(arr).min().getAsDouble();
System.out.println(min);
}
}
uj5u.com熱心網友回復:
您可以創建一個陣列索引流,從 0 到arr.length(不包括):
Optional<Integer> minIndex = IntStream.range(0, arr.length).boxed()
.min(Comparator.comparingDouble(i -> arr[i]));
請注意,這是可選的,因為陣列可能為空。此外,當有多個最小值時,未指定回傳哪個索引。在我使用的實作(OpenJDK 17)中,它回傳第一個索引。
如果你想控制你得到的最小索引,你可以這樣做:
Optional<Integer> minIndex = IntStream.range(0, arr.length).boxed().reduce(
// gets the first one's:
(a, b) -> arr[a] <= arr[b] ? a : b
// gets the last one's:
// (a, b) -> arr[a] < arr[b] ? a : b
);
uj5u.com熱心網友回復:
int index;
for (int i = 0; i < arr.length; i ){
double d = arr[i];
if (d == min){
index = i;
break;
}
}
uj5u.com熱心網友回復:
下面是如何在不遍歷陣列索引并嘗試for用流模擬 -loop 的情況下完成的。
而且我們還可以沿途獲取實際的最小值。
為此,我們可以使用DoubleStream.collect()which 期望三個引數:
Supplier<R>supplier - 提供一個可變物件,用作資料容器;ObjDoubleConsumer<R>accumulator - 確定流元素應該如何在供應商提供的可變收集器中累積;BiConsumer<R,R>combiner - 在并行執行流時合并部分結果。
作為應該由供應商提供的可變容器,我們可以使用陣列double[](如果您查看旨在累積原始值的收集器的源代碼,即 summingInt(),summingDouble()等,您可能會發現一些相似之處)。
double[] arr = {263.5, 393.75, 5.0, 289.75};
double[] min = Arrays.stream(arr)
.collect(
() -> new double[]{0, -1, 0}, // supplier
(double[] res, double next) -> { // accumulator
res[2] ; // element count
if (res[1] == -1 || res[0] > next) {
res[0] = next; // min value
res[1] = res[2] - 1; // corresponding index (element count - 1)
}
},
(left, right) -> { // combiner
if (left[0] > right[0]) {
left[0] = right[0];
left[1] = left[2] right[1];
}
left[2] = right[2];
}
);
System.out.printf("Min value is %s at index: %d", min[0], (int) min[1]);
輸出:
Min value is 5.0 at index: 2
上面顯示的用于確定最小值和跟蹤消耗元素數量的邏輯可以封裝到一個class(如@Holger所建議的)中,它將用作陣列的累積型別。
為了方便起見,我實作DoubleConsumer了介面,它的方法accept()將用于實作accumulator。并且 methodmerge()將在combiner中使用。
public static class MinValueAndIndex implements DoubleConsumer {
private int totalCount;
private int index;
private double min;
@Override
public void accept(double value) {
if (totalCount == 0 || value < min) {
min = value;
index = totalCount;
}
totalCount ;
}
public void merge(MinValueAndIndex other) {
if (min > other.min) {
min = other.min;
index = totalCount other.index;
}
totalCount = other.totalCount;
}
// getters
}
流看起來像這樣:
double[] arr = {263.5, 393.75, 5.0, 289.75};
MinValueAndIndex valueIndex = Arrays.stream(arr)
.collect(
MinValueAndIndex::new,
MinValueAndIndex::accept,
MinValueAndIndex::merge
);
System.out.printf("Min value is %s at index: %d", valueIndex.getMin(), valueIndex.getIndex());
輸出:
Min value is 5.0 at index: 2
uj5u.com熱心網友回復:
您可以使用自定義類將索引和該索引處的值放在一起。找到具有最小值的索引的任務變得微不足道,您可以一次找到索引和值。
記錄一下就完美了,如果你使用java 14之前的版本,你可以使用普通類。
public record IndexValue(int index, double value) {
}
用法示例:
public class Test {
public static void main(String[] args) {
double[] arr = {263.5, 393.75, 5.0, 289.75};
IndexValue min = IntStream.range(0, arr.length) //stream indexes
.mapToObj(i -> new IndexValue(i, arr[i])) //map index and value together using the class
.min(Comparator.comparing(IndexValue::value)) //find minimum by comparing values
.orElseGet(() -> new IndexValue(-1, Double.MAX_VALUE)); //supply default value suiting your needs, if array was empty
System.out.println("Min index value - " min);
}
}
列印 - Min index value - IndexValue[index=2, value=5.0]。此流中的所有操作都是無干擾和無狀態的,并且可以安全地并行執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/535339.html
標籤:爪哇数组java流
