「//fix this/」の記事インデックス

//fix this/ Javaコードの間違いをさがせ!


このシリーズは、あなたのコーディング・スキルを試すコーナーです。毎号オラクルのJavaエバンジェリストたちが、Javaコードに関する難問を出題し、正解と解説を掲載します。是非、毎号チャレンジして貴方のコーディング能力の向上にお役立て下さい。


第14回目 (Java Magazine 2014/May-Juneからの出題)


1. 今回のテーマ 「Stream API」 

ここに、Java SE 8の新しいStream APIを使用して、テキスト・ファイル内でもっとも長い行の長さを返すコードがあります。長さではなく行そのものを返すためには、どのような変更が必要でしょうか。



2. コード

BufferedReaderクラスのlines()メソッドは、Java SE 8で新しく導入されたもので、ファイル内のテキスト行であるStringのストリームを返します。このストリームがmapToInt()メソッドに渡され、String.length()へのメソッド参照を関数として使用してIntStreamが生成されます。終端操作であるmax()は、ストリーム内の最大値を識別して、OptionalIntオブジェクトを返します。get()メソッドはOptionalIntの値を返し、この値がintにオート・アンボクシングされて変数longestに代入されます。


以下のコードを見てください。


BufferedReader reader = new BufferedReader(new FileReader
  ("foo.txt"));

 int longest = reader.lines().mapToInt(String::length)
  .max().get(); 

3.正しいのはどれ?

ファイル内でもっとも長い行を返すには、このコードをどう変更すればよいでしょうか。
以下の中から正しい変更方法を選んでください。

1) String longestLine = reader.lines().max(String::longest)
     .orElse("");

2) String longestLine = reader.lines().reduce((a, b)
     -> a.length() > b.length() ? a : b).orElse("");

3) String longestLine = reader.lines().reduce("", (a, b)
     -> a.length() > b.length());

4) String longestLine = reader.lines().max((a, b)
     -> b.length() – a.length()).orElse("");

5) String longestLine = reader.lines().sorted((a, b)
     -> a.length() - b.length()).findFirst()
     .orElse("");

<ヒント>
再帰処理を使用した解決方法について考えてみましょう。






【答え】

正解は 2)です。単一の結果(このケースでは、ファイル内でもっとも長い文字列)を生成するには、ストリームに対してリデュース処理を実行する必要があります。
reduce() メソッドは折りたたみ関数の形式を取っており、1つの関数をストリーム内の各要素に対して適用します。2)の回答では、2 つの文字列の長さを比較して長い方を返す関数が適用されます。


<< 第13回へ戻る I 第15回へ進む >>

「//fix this/」の記事インデックス