質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

2817閲覧

Java8のStream APIの一部処理への委譲がCollection側に実装されていないのはなぜでしょう?

nyago_d

総合スコア178

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2014/11/26 14:37

ちょっと気になったので質問させてください。

たとえば、Java8でリストにフィルタをかける場合には以下のような記述をすると思います。

List<String> list = Arrays.asList("Galileo", "Helios", "Indigo", "Juno", "Kepler", "Luna");
List<String> filterList = list.stream()
.filter(s -> s.contains("a"))
.collect(Collectors.toList());

groupByコレクターのような戻り方のコレクション自体が変わるパターンは難しいとは思いますが、
filterやmapなどの中間処理メソッドはCollectionインタフェースにそのまま定義されていれば、

List<String> filterList = list.filter(s -> s.contains("a"));

のようにコードがもう少し短くなるのになぁと思ってしまいます。

インタフェースへのデフォルト実装も導入されたことですし、
処理委譲があってもいいのにと思うのですが、なにか問題があったりするのでしょうか?

ちなみに、Streamはプリミティブも扱えるのが素敵ですよね。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

List<String> filterList = list.filter(s -> s.contains("a"));
のようにコードがもう少し短くなるのになぁと思ってしまいます。

Listというのは中身の数が決まった箱です。一方Streamはそうではありません。
例えば中身が100万あるListをlist.map(...).filter(...).map(...) のように書くと
100万のサイズを持つ箱が何回も作り直されてしまい、これはパフォーマンス上の問題になります。
初心者がうっかりそうしないように、Listは直接 filter というメソッドを持たないのだと思います。

Javaに似た言語 C# では、Listから直接filterと同様のメソッドWhereを呼び出すことができますが、戻り値はListではありません。

IList<int> numbers = getNumbers(); IEnumerable<int> evens = numbers.Where(x => x % 2 == 0); // IEnumerableはJavaのStream相当 IList<int> evenList = numbers.Where(x => x % 2 == 0).ToList(); // Listを作り直す

投稿2014/11/27 12:37

hello-world

総合スコア1342

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コレクションの新しいインスタンスをどうやって生成するか、がポイントかと思います。
それができたとしても元のコレクションの方と同じ型を得るには、キャストするしかなさそうです。

手前味噌で恐縮ですが...私も以前、同様のことを考えて、こういう記事を書きました。
架空の拡張-filter,mapをStreamを使わずに組み込むとしたら - argius note

投稿2014/11/27 01:27

argius

総合スコア9394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

適当に思っただけで合ってるかどうかはわかりませんが...

filterなどのインターフェースはStreamとしてのものでListのものではないということだと思います。もしListがStreamとして扱ってよい類のものなら別ですが役割はやはり別ではないでしょうか?Streamは文字通りデータの流れを扱うものであってListはデータを保持する役割と感じます。

filterが最初からあると確かに便利と感じますが、ではストリームの他のメソッドはなくてもいいのかと考えると...便利そうだからということで無秩序に機能を追加するのはListというもののインターフェースを壊してしまう危険があるように思います。それよりもstream()のみ追加してそれを解してストリームの全機能を使えるとした方があるべき姿ということなのかも知れません。

ちなみにListにfilterというメソッドがあったとすると自分なら「Listの全要素からprecicateにより選択した要素だけを持つListを返す」というメソッドをイメージします。結果がStreamですといわれるとなんでそんな機能がListにあるの?と思ってしまうような気がします。

投稿2014/11/26 15:11

KSwordOfHaste

総合スコア18402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2014/11/26 15:30

Listと書いてしまいましたがCollectionというべきでした
KSwordOfHaste

2014/11/27 04:28

全体的に勘違いコメントでした。Collection->StreamAPIの加工->Collectionをもっとすっきりかけないかという議論なだけなんですね。失礼しました。
guest

0

お三方とも貴重なご意見ありがとうございます。

悩みましたがhello-worldさんの解答が一番なるほどと思ったためベストアンサーとさせていただきます。
確かに複数回の中間処理をするたびにコレクションを作り直すのは微妙ですね。
とはいってもJava7までであれば普通にやっている気もしますが…。

たとえばListインタフェースに以下のようなメソッドを書いたらダメか?
というようなイメージでした。

default List<E> filter(Predicate<? super E> predicate) { return this.stream().filter(predicate).collect(Collectors.toList()); } default <R> List<R> map(Function<? super E, ? extends R> mapper) { return this.stream().map(mapper).collect(Collectors.toList()); }

argiusさんの記事を読ませていただきましたが、とても参考になりました。
そしてただの処理委譲をしようとしていたずぼらな私よりも
より高度な考察をなさっていてなるほどなぁと思うことしきりです。

インスタンスの生成型というのは盲点で、Collectors#toListの実装を眺めてみたりしましたが、
これってArrayList固定になっていて、それ以外を使う場合にはファクトリを渡すのですね。
あまり考えたこともありませんでした。

とても良い考察ができたことに感謝いたします。

投稿2014/11/27 13:19

nyago_d

総合スコア178

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyago_d

2014/11/27 13:35

あれ…ここに書くのはなんか変ですね…。
argius

2014/12/01 05:11

詳細な事後レポートをまとめるのにはコメント欄だと狭いので、私は回答欄で投稿しても良いと思いますよ。コメント欄だと修正が利きませんし。 拙筆を参考にしていただけたようで、何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問