Javaのラムダ式で戻り値とvoidの使い方を解説!returnの書き方も完全理解
生徒
「Javaのラムダ式で戻り値を使いたいとき、どう書いたらいいんですか?」
先生
「戻り値がある場合はreturnを使うこともできますが、実は省略もできるんですよ。」
生徒
「えっ、省略できるんですか?void型のときはどうなるんですか?」
先生
「では、Javaのラムダ式における戻り値とvoidの扱い、そしてreturnの書き方を順番に学んでいきましょう。」
1. ラムダ式での戻り値とは
Javaのラムダ式は「関数型インタフェース」の形に合わせて書きます。インタフェース側が戻り値の型を決めているので、ラムダ式はその型の値を返す必要があります(例:FunctionやBiFunctionは値を返す)。
基本構文は次のとおりです。まずは「式だけの1行」と「複数行ブロック」の2パターンを覚えましょう。
引数 -> 式 // 1行:returnも{}も省略OK(式の値がそのまま戻る)
引数 -> { 処理; return 値; } // 複数行:{}とreturnが必要
import java.util.function.Function;
import java.util.function.BiFunction;
// 1行:平方を返す(式=戻り値)
Function<Integer, Integer> square = x -> x * x;
// 複数行:メッセージを挟んでから長さを返す(return必須)
Function<String, Integer> len = s -> {
System.out.println("文字列: " + s);
return s.length();
};
// 2引数を足し算して返す(BiFunctionは2引数+戻り値)
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
ポイントは「式が1行ならreturn省略」「複数行は{}+return」。戻り値が必要な型(例:Function<T,R>)に対して値を返さないとコンパイルエラーになるので、まずはこの型と書き方の対応だけ意識すればOKです。
2. 戻り値を返すラムダ式の基本
JavaのFunctionを使った戻り値付きのラムダ式の基本は以下の通りです。
Function<Integer, Integer> square = x -> x * x;
このように、x -> x * xという1行の式の場合、return文やブロックは不要です。
ただし、処理が複数行にわたるときは、{}で囲み、returnを明示する必要があります。
Function<Integer, Integer> square = x -> {
int result = x * x;
return result;
};
3. void型(戻り値なし)のラムダ式
Javaで戻り値がないラムダ式は、ConsumerやRunnableなどの関数型インタフェースを使います。戻り値がvoidのときはreturnを書く必要はありません。
Consumer<String> printer = message -> System.out.println("メッセージ:" + message);
複数行の処理を行いたい場合はブロックにして記述しますが、それでも戻り値は不要です。
Runnable runTask = () -> {
System.out.println("処理を開始します");
System.out.println("処理が終了しました");
};
4. returnの書き方と省略ルール
Javaのラムダ式でreturnを使うかどうかは、処理の行数に応じて変わります。
- 1行のみの場合:returnを省略できる
- 複数行の場合:returnが必要、ブロックも必要
例えば、以下のように1行だけならreturnは書かなくてもOKです:
Function<String, Integer> strLength = s -> s.length();
しかし、2行以上の処理がある場合は次のように記述します:
Function<String, Integer> strLength = s -> {
System.out.println("文字列:" + s);
return s.length();
};
5. 戻り値・voidの違いをサンプルで確認
import java.util.function.*;
public class LambdaReturnVoidExample {
public static void main(String[] args) {
// 戻り値あり
Function<Integer, Integer> doubleIt = x -> x * 2;
int result = doubleIt.apply(10);
System.out.println("2倍の値:" + result);
// 戻り値なし(void)
Consumer<String> sayHello = name -> System.out.println("こんにちは、" + name + "さん!");
sayHello.accept("太郎");
// 複数行+returnあり
Function<Integer, String> judge = n -> {
if (n > 0) return "正の数";
else if (n < 0) return "負の数";
else return "ゼロ";
};
System.out.println(judge.apply(-5));
}
}
▼ 実行結果:
2倍の値:20
こんにちは、太郎さん!
負の数
6. returnの注意点とエラー例
Javaのラムダ式でreturnを使う際には以下の点に注意が必要です。
- returnを書くときは必ず
{}のブロックで囲む - 戻り値があるインタフェースでreturnを書かないとコンパイルエラー
- 戻り値がない(void)インタフェースでreturnを書くとエラーになることも
初心者のうちは、returnの有無と戻り値の有無を明確に意識するようにしましょう。
7. よく使われる戻り値付き関数型インタフェース
Javaで戻り値を返すラムダ式を書く際には、以下のインタフェースを覚えておくと便利です。
Function<T, R>:1つの引数を受け取り、結果を返すBiFunction<T, U, R>:2つの引数を受け取り、結果を返すPredicate<T>:引数を受け取り、true/falseを返すUnaryOperator<T>:引数と戻り値が同じ型の関数
一方、戻り値がない場合は以下のインタフェースを使用します。
Consumer<T>:引数を受け取り、何も返さないRunnable:引数も戻り値もなし
まとめ
Javaのラムダ式は、関数型インタフェースに合わせて実装を書くのが大前提です。本記事の要点は「戻り値があるか」「void(戻り値なし)か」、そして本体が「一行の式か」「複数行のブロックか」を見分け、returnの有無を正しく選ぶことでした。
return省略可/複数行のブロック → {}とreturn必須。キーワード:Java ラムダ式・戻り値・void・return・Function・Predicate・Consumer・Runnable・ストリームAPI
戻り値ありの代表は Function・BiFunction・Predicate・UnaryOperator。入力から結果を返す役で、データの変換・集約・真偽判定を簡潔に表現できます。戻り値なし(void)の代表は Consumer・Runnable。表示・記録・通知などの副作用を担い、途中で止めたいときはreturn;で処理のみ終了します(値は返さない)。
- Function<T,R>:ひとつ渡してひとつ返す(例:文字列→長さ)
- BiFunction<T,U,R>:二つ渡して一つ返す(例:合計・結合)
- Predicate<T>:真偽判定(例:空かどうか)
- UnaryOperator<T>:同型で整形(例:trim・大文字化)
- Consumer<T>:受け取って処理(例:ログ出力)
- Runnable:引数も戻り値もなし(例:前後処理)
- ※ 値を返す
return 値;は書かない。打ち切りはreturn;。
すぐ試せるサンプル(戻り値とvoidの使い分け)
変換=Function、判定=Predicate、出力=Consumer。短い処理は一行で、少し複雑ならブロック+returnにしましょう。
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class SummarySample {
public static void main(String[] args) {
List<String> list = Arrays.asList(" apple", "", "Banana ", " ", "Cherry");
// 変換(戻り値あり):空白を取り大文字化
Function<String, String> normalize = s -> {
if (s == null) return "";
return s.trim().toUpperCase(); // ブロックなのでreturn必須
};
// 判定(戻り値あり=boolean):空を除外
Predicate<String> nonBlank = s -> !s.isBlank(); // 一行なのでreturn省略
// 出力(戻り値なし):長さを表示
Consumer<Integer> printLen = n -> System.out.println("長さ:" + n);
list.stream()
.map(normalize) // Functionで変換
.filter(nonBlank) // Predicateで絞り込み
.map(String::length) // 長さへ変換
.forEach(printLen); // Consumerで出力
}
}
- 一行の式は
return省略、複数行ブロックは{}+return。 - 分岐は全経路で値を返す(未到達・未返却を作らない)。
- voidのラムダでは値を返さない(必要なら
return;で終了のみ)。 - 型(
Function<T,R>/Predicate<T>/Consumer<T>)から設計を逆算。 - 短いものは式、複雑なものはブロックに分け、読みやすさを優先。
用語ミニ辞典(検索キーワードの理解に)
ラムダ式: 短い関数表現。「引数」→「本体」の形で書く。
関数型インタフェース: 抽象メソッドが一つ。ラムダ式の受け皿。
戻り値: 処理結果として呼び出し元に返す値。
void: 何も返さない型。表示・記録・通知に向く。
return: 処理の終了と返却を示す。ブロックでは明示が必要。
生徒
「式で書けるときはreturnいらなくて、ブロックならreturnが必要、まずはここを守れば良さそうですね。」
先生
「その調子。さらに、関数型インタフェースが戻り値の型を決めるから、Functionなら『何を返すか』を先に決めると迷いません。」
生徒
「Predicateは真偽、Consumerは出力、Runnableは実行だけ。用途が分かれているからストリームの読み書きもすっきりしますね。」
先生
「うん。短い処理は一行の式、少し複雑ならブロック+return。このリズムで書けば、Javaのラムダ式・戻り値・void・returnの使い分けは自然と身につきますよ。」