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

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

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

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

Q&A

解決済

2回答

1838閲覧

ラムダ式について

take_take

総合スコア21

Java

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

0グッド

1クリップ

投稿2017/03/14 10:19

ラムダ式について質問です。
下記の【ソースコード1】について、4~7行目でラムダ式を使用して
関数型インタフェースのapplyメソッドを実装していますが、ラムダ式で
メソッド名を記述しなくてよいのは、関数型インタフェースは抽象メソッドを
1つ持っているインタフェースであり、ラムダ式によって実装しているメソッドは、
関数型インタフェースが唯一持っている抽象メソッドに対しての処理であると
認識されるためだという認識です。

この認識ですと、下記の【ソースコード2】の4~5行目のように抽象メソッド以外の
デフォルトメソッドなどはラムダ式で記述できないことになってしまうのですが、この認識が
間違っているのでしょうか。

ラムダ式についての正しい回答を宜しくお願い致します。

【ソースコード1】
0. import java.util.function.Function;
0. public class Sample{
0. public static void main(String[] args){
0. Function<String, String> obj = (String str) -> {
0. return "Hello" + str;
0. };
0. String str = obj.apply("Test");
0. }
0. }

【ソースコード2】
0. import java.util.*;
0. public class Sample2{
0. public static void main(String[] args){
0. List<String> list = Arrays.asList("red","blue","green");
0. color.replaceAll((String str) -> {return s.toUpperCase()});
0. }
0. }

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

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

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

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

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

guest

回答2

0

抽象メソッド以外のデフォルトメソッドなどはラムダ式で記述できない

おっしゃるとおりです。List#replaceAllの引数はUnaryOperatorですが、このインターフェースには抽象メソッド一つと3つほどのデフォルトメソッドが定義されてますがラムダ式で表現できるのは抽象メソッドのみです。

Javaを離れて計算機科学一般においてラムダ式が何を意味するかと言えば「単一の関数を表記するためのもの」と捉えることができると思います。古くはLispなどにありましたし、今日は色々な言語に見られますが、いずれの言語でも「単一の関数の実装」であることは同じだと思います。

Javaでは「関数」という新たな言語仕様を導入するのではなく「単一の抽象メソッドのみを持つinterface」を「関数のインターフェースの定義」と見做してそれを実装する具象クラス(およびそのインスタンシエーション)を行うことで、いわゆる第一級関数の実体を表現できるようにしたのでしょう。そうすることで言語仕様を大きく変更しなくて済むため都合がよかったのだと思います。

以上のように考えるとラムダ式は「Javaのinterfaceを実装するもの」なのではなく「関数を表現するもの」と考えるべきであり、デフォルトメソッドをオーバーライドできたりすることは本質的な意味からは不必要なもの(むしろおかしい機能)と言えると思います。

投稿2017/03/14 12:31

編集2017/03/14 16:00
KSwordOfHaste

総合スコア18394

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

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

take_take

2017/03/14 12:39

ラムダ式の認識としては間違えではなかったのですね。ラムダ式についてそこまで深く考えたことはなかったですが、『単一の関数の実装』と考えると 理解しやすい気がしました。 有難うございます!
guest

0

ベストアンサー

ソースコード1では、Functionという関数型インタフェースの実装としてラムダ式を利用しています。
ソースコード2では、List#replaceAllの引数であるUnaryOperatorという関数型インタフェースの実装としてラムダ式を利用しています。
List#replaceAllの実装を行っているわけではありません。

ソースコード2はこう書くことも出来ます。

java

1List<String> list = Arrays.asList("red","blue","green"); 2UnaryOperator<String> obj = (String str) -> {return s.toUpperCase()}; 3list.replaceAll(obj);

投稿2017/03/14 11:38

7tsuno

総合スコア310

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

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

take_take

2017/03/14 11:54

引数のインタフェースの実装なのですね。書き方を変えると分かりやすかったです。有難うございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問