2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Java Gold ラムダ式(関数)について

Posted at

ラムダ式とは何か

ラムダ式は、匿名関数(名前を持たない関数)を簡潔に表現するための構文です。従来、匿名クラスを使用して記述していたコードを、よりシンプルに書くことができます。これにより、コードの可読性が向上し、開発効率もアップします。

例:匿名クラスとラムダ式の比較

// 匿名クラスを使用
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, World!");
    }
};

// ラムダ式を使用
Runnable runnable = () -> System.out.println("Hello, World!");

ラムダ式の基本構文

ラムダ式の基本的な構文は以下のとおりです。

(引数リスト) -> { 処理内容 }

引数リスト:関数が受け取る引数をカンマで区切って列挙します。
矢印演算子(->):ラムダ式であることを示します。
処理内容:メソッドの本体を中括弧 {} 内に記述します。

シンプルな例

// 引数なし、戻り値なし
() -> System.out.println("Hello, Lambda!");

// 引数あり、戻り値なし
(String message) -> System.out.println(message);

// 引数あり、戻り値あり
(int x, int y) -> x + y;
省略可能な部分

引数の型はコンパイラが推論できる場合、省略可能。
引数が1つの場合、括弧 () を省略可能。
処理内容が単一の式の場合、中括弧 {} と return キーワードを省略可能。

省略例

// 型と括弧を省略
message -> System.out.println(message);
// 中括弧とreturnを省略
(x, y) -> x + y;

関数型インターフェース

ラムダ式は関数型インターフェースを実装するために使用されます。関数型インターフェースとは、抽象メソッドを1つだけ持つインターフェースのことです。

代表的な関数型インターフェース

Consumer<T>:引数を1つ取り、戻り値なし。(コンシューマー)
Function<T, R>:引数を1つ取り、戻り値あり。(ファンクション)
Predicate<T>:引数を1つ取り、boolean を返す。(プレディケート)
Supplier<T>:引数なし、戻り値あり。 (サプライヤー)
Comparator<T>:2つの引数を取り、整数を返す。(コンパレーター)

早見表

メソッド 役割 使用する関数型インターフェース
forEach 各要素に対する処理 Consumer< T >
map 各要素の変換 Function< T , R >
filter 条件に合う要素を抽出 Predicate< T >
sort 要素の並べ替え Comparator< T >
reduce 要素の集約 BinaryOperator< T >
ifPresent 値が存在する場合の処理 Consumer< T >
submit (スレッド) タスクの非同期実行 Runnable or Callable< V >
collect(toMap) リストやセットをマップに変換 Function< T , K >, Function< T, V >
peek 各要素に処理を行い、ストリームを返す Consumer< T >
allMatch すべての要素が条件を満たすか判定 Predicate< T >
anyMatch いずれかの要素が条件を満たすか判定 Predicate< T >
noneMatch すべての要素が条件を満たさないか判定 Predicate< T >
findFirst 最初の要素を取得 Supplier>
findAny 任意の要素を取得(並列処理に適用) Supplier< Optional < T > >
max 最大値を取得 Comparator< T >
min 最小値を取得 Comparator< T >
groupingBy(Collectors) グループ化しマップに変換 Function< T , K >
partitioningBy(Collectors) 条件で2つのグループに分ける Predicate< T >
flatMap 要素を展開して一つのストリームにする Function< T, Stream< R>>

ラムダ式の活用例

コレクションの操作

forEachメソッド
コレクションの各要素に対して処理を行います。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name));

sortメソッド
リストの要素を特定の基準で並べ替えます。

names.sort((a, b) -> a.length() - b.length());

ストリームAPIとの連携

mapメソッド
各要素に関数を適用して、新しいストリームを生成します。

List<Integer> nameLengths = names.stream()
    .map(name -> name.length())
    .collect(Collectors.toList());

filterメソッド
条件に合致する要素だけを抽出します。

List<String> shortNames = names.stream()
    .filter(name -> name.length() <= 3)
    .collect(Collectors.toList());

reduceメソッド
ストリームの要素を集約して1つの結果にまとめます。

int totalLength = names.stream()
    .map(name -> name.length())
    .reduce(0, (a, b) -> a + b);

並行処理での使用

Runnable(ラナブル)とCallable(カラブル)
スレッドやタスクの実行で使用されます。

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("Task is running"));
executor.shutdown();

Optionalクラスとの組み合わせ

ifPresentメソッド(イフプレゼント)
値が存在する場合に処理を実行します。

Optional<String> optionalName = Optional.of("Alice");
optionalName.ifPresent(name -> System.out.println("Name: " + name));

mapメソッド
Optionalの値を変換します。

Optional<Integer> nameLength = optionalName.map(name -> name.length());

メソッド参照とラムダ式

ラムダ式が既存のメソッドをそのまま呼び出すだけの場合、メソッド参照を使用してより簡潔に記述できます。

シンタックス
ClassName::methodName
object::methodName

// ラムダ式を使用
names.forEach(name -> System.out.println(name));

// メソッド参照を使用
names.forEach(System.out::println);
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?