メソッドチェーンの全体像
メソッドチェーンは「メソッドの戻り値に対して、さらにメソッドを続けて呼ぶ」書き方です。オブジェクトが「次も同じ型(または関連型)を返す」ように設計されていると、ドットを繋いで流れるように記述できます。読みやすさ(左から右へ処理が流れる)と、不要な一時変数を減らせるのが利点です。Java では String/Optional/Stream/Builder などが典型的で、設計側は「this を返す」「新インスタンスを返す」などの方針で実現します。
仕組みの基本と返り値の型
同じ型を返すチェーン
「同じオブジェクトを返す」か「同じ型の新しいオブジェクトを返す」ことで、次のメソッドを続けられます。可変(mutability)なら this を返し、不変(immutability)なら新インスタンスを返すのが基本です。
// 可変:StringBuilder は自分自身を返す(append の戻りが this)
String s = new StringBuilder()
.append("Hello")
.append(" ")
.append("World")
.toString();
// 不変:String は新しい文字列を返す
String t = " hello ".trim().toUpperCase().repeat(2); // "HELLOHELLO"
Java型が段階的に変わるチェーン
途中で型が変わる設計(Stream→Optional→値など)も自然に繋げられます。各段階で「次の操作に意味のある型」を返すことが重要です。
int len = java.util.Optional.of("hello")
.map(String::toUpperCase)
.map(String::length)
.orElse(0); // 最終段は値に落とす
Javaよく使うメソッドチェーンの例
文字列処理(不変の連鎖)
String result = " Tokyo "
.trim() // 前後空白除去
.toUpperCase() // 大文字化
.replace("TOKYO", "江東区") // 範囲置換(例)
.concat(" JAPAN"); // 連結
Java不変オブジェクトでは「元は変わらない」「新しい値を返す」ため、安心して繋げられます。
StringBuilder(可変+this返し)
String msg = new StringBuilder()
.append("ID=").append(42).append(", ")
.append("OK=").append(true)
.toString();
Java内部のバッファを書き換えつつ this を返すので、パフォーマンスと可読性が両立します。
Stream(宣言的に変換→絞り込み→集約)
int sum = java.util.stream.Stream.of(1, 2, 3, 4, 5)
.filter(x -> x % 2 == 1) // 奇数だけ
.map(x -> x * x) // 二乗
.reduce(0, Integer::sum); // 合計 → 35
Java「変換(map)→絞り込み(filter)→集約(reduce)」の流れが左から右へ可視化されます。
Optional(存在すれば進める、安全な連鎖)
String label = java.util.Optional.ofNullable(getUserName()) // null 安全
.map(String::trim)
.filter(s -> !s.isEmpty())
.orElse("(no name)");
Javanull チェックを明示的に書かずに「存在する場合だけ進む」連鎖ができます。
自作の Fluent API(設計の型)
this を返す可変オブジェクト(ビルダー)
連鎖させたい設定系 API は「setter が this を返す」形にします。最終段で build() を返すと「組み立て完了」が明確になります。
final class MailBuilder {
private String to, subject, body;
public MailBuilder to(String v) { this.to = v; return this; }
public MailBuilder subject(String v) { this.subject = v; return this; }
public MailBuilder body(String v) { this.body = v; return this; }
public Mail build() { return new Mail(to, subject, body); }
}
Mail mail = new MailBuilder()
.to("user@example.com")
.subject("Hello")
.body("Welcome!")
.build();
Java不変オブジェクトは「新インスタンスを返す」
可読性と安全性を重視するなら、操作ごとに新しい値オブジェクトを返す設計が有効です。
record Money(int amount, String currency) {
public Money add(int delta) { return new Money(amount + delta, currency); }
public Money in(String newCur) { return new Money(amount, newCur); }
}
Money m = new Money(100, "JPY").add(50).in("USD");
Java重要ポイントの深掘り:読みやすさと安全性
行の分割と視線誘導
長いチェーンは「段ごとに改行+インデント」で読みやすくします。各段の「意図」が一目で分かる並びにします。
var users = repo.findAll()
.stream()
.filter(u -> u.active())
.sorted(java.util.Comparator.comparing(User::name))
.toList();
Java副作用は「最後か、明確な段」で
チェーン途中で I/O やミューテーションを混ぜると、意図が不透明になります。基本は「変換の連鎖→最後に副作用(保存・出力)」の構造に分けます。
var data = read() // 入力
.transform() // 純粋変換
.validate(); // 検証
save(data); // 出力(副作用)は最後
Javanull と例外の扱い
チェーンは「途中で null が入ると崩れる」ため、Optional を入口に挟む、または早期にガードします。例外を投げる可能性がある段は try の境界を明確にすると、失敗の位置が特定しやすくなります。
String res = java.util.Optional.ofNullable(source)
.map(String::trim)
.orElse("(empty)");
Javaアンチパターンと対策
無限に長いチェーン
読み手が追えない長さは逆効果です。意味の塊でメソッド抽出し、名前に意図を込めて短く保ちます。
String normalized = normalizeForSearch(input); // 中で trim/toLowerCase/全角半角などを連鎖
Java途中の状態を使ってデバッグできない
各段の結果を見たい時は、一時変数に落とすか、peek(Stream限定)を使います。無理に一行で完結させないこと。
var s1 = raw.trim();
var s2 = s1.toUpperCase();
System.out.println(s2);
Java可変と不変の混在で混乱
同じチェーンに「不変(新インスタンス)」と「可変(this 返し)」が混ざると挙動の予想が難しくなります。流儀を統一するか、役割で分けましょう。
例題で身につける
例 1: ユーザー一覧をフィルタして整形
var names = users.stream()
.filter(User::active)
.map(User::name)
.map(String::trim)
.filter(s -> !s.isEmpty())
.sorted()
.toList();
Java例 2: 住所文字列の整形(不変連鎖)
String addr = " 東京都 江東区 "
.trim()
.replaceAll("\\s+", " ")
.toUpperCase(java.util.Locale.JAPAN);
Java例 3: Builder で設定を流れるように
var req = new RequestBuilder()
.endpoint("/api/orders")
.timeoutMs(3_000)
.header("Auth", "token")
.build();
Java例 4: Optional で安全に取得→整形
String title = java.util.Optional.ofNullable(post.getTitle())
.map(String::trim)
.filter(t -> !t.isEmpty())
.orElse("(untitled)");
Java仕上げのアドバイス(重要部分のまとめ)
メソッドチェーンは「戻り値を次へ繋ぐ」書き方で、読みやすさと一貫性が強みです。可変なら this を返す、不変なら新インスタンスを返す——どちらかの流儀で統一し、長すぎる連鎖は分割して意図を名前に込める。副作用は最後に寄せ、null は Optional で安全に進める。Stream の宣言的な連鎖は強力だが、デバッグしづらいと感じたら躊躇なく一時変数へ落とす——この型が身につけば、読みやすく拡張しやすいコードが自然に書けます。
