1. ホーム
  2. java

[解決済み] Java 8のラムダを使ってストリームからアイテムの範囲を取得する方法は?

2023-06-05 14:45:49

質問

以前の質問で [ どのようにJava 8で動的にフィルタリングを行うには? ] Stuart Marksは素晴らしい回答をし、ストリームからのtopNとtopPercentの選択を処理するためのいくつかの有用なユーティリティを提供しました。

私はそれらを彼のオリジナルの回答からここに含めます。

@FunctionalInterface
public interface Criterion {
    Stream<Widget> apply(Stream<Widget> s);
}

Criterion topN(Comparator<Widget> cmp, long n) {
    return stream -> stream.sorted(cmp).limit(n);
}

Criterion topPercent(Comparator<Widget> cmp, double pct) {
    return stream -> {
        List<Widget> temp =
            stream.sorted(cmp).collect(toList());
        return temp.stream()
                   .limit((long)(temp.size() * pct));
    };
}

ここで私が質問するのは:

[1] ある程度の数のアイテムがあるストリームから、3から7までのトップアイテムを取得する方法。

topNFromRange(Comparator<Widget> cmp, long from, long to) = topNFromRange(comparing(Widget::length), 3L, 7L)

は { A3, A4, A5, A6, A7 } を返します。

一番簡単な方法は、元から上位7位[ T7 ]を取得し、元から上位3位[ T3 ]を取得し、T7 - T3 を取得する方法だと思います。

[2] ある量のアイテムがあるストリームから、上位10%から上位30%のアイテムを取得する方法、つまりストリームにX1、X2 ... X100のアイテムがある場合、呼び出しは

topPercentFromRange(Comparator<Widget> cmp, double from, double to) = topNFromRange(comparing(Widget::length), 0.10, 0.30)

は { X10, X11, X12, ..., X29, X30 } を返します。

一番簡単な方法は、元から上位30% [ TP30 ]を取得し、元から上位10% [ TP10 ]を取得し、TP30 - TP10 を取得する方法だと思います。

上記の状況を簡潔に表現するために、Java 8 Lambdaを使用する良い方法は何でしょうか?

どのように解決するのですか?

ユーザーskiwiはすでに 回答済み は、質問の最初の部分です。2番目の部分は

(2) ある程度のアイテムがあるストリームから、上位10%から上位30%のアイテムを取得する方法...。

これを行うには、次のようなテクニックを使う必要があります。 topPercent で、私の 答え を他の質問に追加しました。つまり、要素のカウントを取得できるようにするために、要素をリストに収集する必要があり、おそらく上流のフィルタリングが行われた後です。

一旦カウントを得たら、次に正しい値を計算し skiplimit を、カウントとパーセンテージを元に作成します。このようにするとうまくいくかもしれません。

Criterion topPercentFromRange(Comparator<Widget> cmp, double from, double to) {
    return stream -> {
        List<Widget> temp =
            stream.sorted(cmp).collect(toList());
        return temp.stream()
                   .skip((long)(temp.size() * from))
                   .limit((long)(temp.size() * (to - from)));
    };
}

もちろん、エラーチェックは fromto . もっと微妙な問題は、いくつの要素を出すかを決めることである。例えば、10個の要素がある場合、それらはインデックス [0..9] にあり、0%、10%、20%、...、90%に相当します。しかし、もし9%から11%の範囲を指定しようとすると、上記のコードでは、期待される10%の要素ではなく、全く要素が表示されないことになります。したがって、パーセンテージの計算を多少調整して、行おうとしていることのセマンティクスに適合させることがおそらく必要でしょう。