この質問に関する最も重要なことは、ラムダ式をStream
APIのような特定のライブラリに渡すと、すべてのライブラリが受け取るのは機能インターフェイスの実装であるということです。 Predicate
のインスタンスその実装が何をするかについての知識がないため、比較によってソートされたデータをフィルタリングするなどのシナリオを悪用する方法はありません。ストリームライブラリは単にPredicate
が比較を行っていることを知らない。
このような最適化を行う実装では、コードを認識し理解しているJVMと、セマンティクスを把握しているライブラリとの対話が必要です。そのようなことは現在の実装では起こらず、少なくとも私が見ることができるように、現在は遠く離れています。
ソースがツリーまたはソートされたリストで、フィルタリングのメリットを得たい場合は、ストリームを作成する前に、ソースで操作しているAPIを使用してソースを操作する必要があります。例えば。私たちは、代わりに行うことができます
// our made-up source
TreeSet<Integer> tree=IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(TreeSet::new));
// the naive implementation
tree.stream().filter(i -> i>=65 && i<91).forEach(i->System.out.print((char)i.intValue()));
のように、私たちはTreeSet
を持っており、特定の範囲内のアイテムを得るためにそれをフィルタリングしたい、としますソート/木の自然を利用する
tree.tailSet(65).headSet(91).stream().forEach(i->System.out.print((char)i.intValue()));
を。
int ix=Collections.binarySearch(list, 65);
if(ix<0) ix=~ix;
if(ix>0) list=list.subList(ix, list.size());
ix=Collections.binarySearch(list, 91);
if(ix<0) ix=~ix;
if(ix<list.size()) list=list.subList(0, ix);
list.stream().forEach(i->System.out.print((char)i.intValue()));
:私たちが代わりにソートされたリストを持っている場合は、コレクション自体は、それがソートだということを知っていないと操作は、その直接利用提供していないとして、ソートされた性質を利用
List<Integer> list=new ArrayList<>(tree);
はより複雑であると言います
もちろん、ここでのストリーム操作は一例に過ぎず、ストリームを一切必要としません。forEach
...
'Map>'を使用できませんか? –
Keppil
@Keppilはいありがとうございます。検討の結果、あなたが提案したものが最も効率的だと思います。他の誰かが、私が探しているコレクションに「Thing」の内部知識が必要だと言ったコメントを削除したので、Mapを介して 'Thing.type'を索引付けするほうがよいでしょう。 – Wernsey