たぶんジョークだと思うんだが「Java8があったらScalaが不要になる」みたいな事を言っている人がいて、本気だとすると、Java8もScalaも見たことないのに言ってるだけだと思う。
ということで一応マジレス?しておく(笑)
- Java8でインターフェースにメソッド(デフォルト実装)が持てるようになった。
- Java8のインターフェースは可視性にpublicしか指定できないが、Scalaのトレイトはpublic以外も可。
- Java8のインターフェースはフィールド(static finalな定数以外)を持てないが、Scalaのトレイトは持てる。
- Java8でStreamが導入された。
- Java8ではプリミティブ用のStreamとオブジェクト用のStreamがあり、mapもそれらに応じてmapToObjやmapToInt等のメソッドがあり、使い分けなければならない。Scalaは全てmapメソッドで出来る。
- Java8のStreamにはzipやdrop・takeWhileといったメソッドが提供されていない。
- Java8のStreamのflatMapはStreamを返す関数しか渡せない。ScalaのflatMapはListでも配列でもOK。
- Java8のStreamは、Listに変換するにはcollectメソッド(Collectors.toList)を使う。ScalaはtoListというメソッドを使う(メソッド名が分かり易いし短い)。
- Java8ではStream以外のコレクションにはmapやfilterといったメソッドは追加されていない。ScalaではStream以外のコレクションにもある。
- ラムダ式
- Java8では変数名が外部スコープと同じになる(ラムダ式の引数に外部と重複した変数名が使えないのは痛い)。
- Java8ではラムダ式の本体から外部スコープの変数にアクセスする場合はその変数がfinalである必要がある。Scalaでは外部スコープの変数の値も書き換えられる。
- Java8では複数の文を書いたらreturnを書く必要がある。
- Scalaにはプレースホルダーがある。
- Optional
- Java8のOptionalは、ScalaのOptionとほぼ遜色ないかな。
- Java8では(Streamと同様に)プリミティブ用のOptionalIntとかがあって、オブジェクト用のOptionalと相互変換できないのが不便だけど。
- メソッド参照
- Scalaでもメソッドを関数として渡すことは出来るが、見た目は(通常のメソッド呼び出しなのか関数オブジェクトを渡しているのかは)分かりにくいかもしれない。
- コンストラクター参照
- Scalaにはコンストラクター参照に当たるものは無い気がする。強いて言えば、コンパニオンオブジェクトのapplyメソッド(コンストラクターの代わり)を関数として渡せるが。
Streamのメソッドが足りない件については、最初は最小限にして、後から追加していくつもりなんじゃないかと思う。(最初から多すぎてもどれを使えばいいのか迷うだけだし^^;)
Stream以外のコレクションにmapやfilterといったメソッドが無いのは、実行性能や理念の問題で敢えて入れていないのだろう。
(例えばListの場合は、もしmapが即時評価だったらmapを複数チェーンすると実行速度が遅くなる。そうなっていたらStreamを介すのが解決策になるわけで、結局Stream以外のmapは使われなくなるだろう)
(例えばListのメソッドは自分自身を操作するので、filterの代わりにremoveIfといったメソッドが加わっていたりする。(filterは、値をフィルタリングした新しい集合を返す。removeIfは、指定された条件で自分自身の中から削除する))
そういや、int用のStreamはIntStreamなのに、int用のOptionalがOptionalInt(「Int」の付く位置が違う)なのは何故だ?^^;
Javaは、バージョン間の上位互換を非常に重視している。(以前のバージョンで書いたソースやコンパイルしたクラスがそのまま新バージョンで動作することを目指している)
その制約の中では、上記に挙げた欠点も、妥当な選択の産物だとは思う。
プリミティブ用のStreamを用意したり、mapToIntやmapToObjによってStreamの種類を変換したりするのも、よく考えたなぁと感心する。
でも使う側からすると、Scalaより面倒なことに変わりはない(苦笑)
※コメント投稿者のブログIDはブログ作成者のみに通知されます