3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Java基礎練習:Stream APIでのmap()の使い方

Posted at

私が最近あるコードレビューをしていてなるほどと思ったコードがありちょっと試してみたことの共有です。

Stream APIの map()

これです。
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-

map

<R> Stream<R> map(Function<? super T,? extends R> mapper)

Returns a stream consisting of the results of applying the given function to the elements of this stream.
This is an intermediate operation.

Type Parameters:
R - The element type of the new stream

Parameters:
mapper - a non-interfering, stateless function to apply to each element

Returns:
the new stream

ここに書かれている通りです。 applying the given function to the elements of this stream ということで、引数に指定した関数をこのストリームの要素たちに行います。

気づき

なるほどと思ったコード(一部改変)
List<HogeHoge> entityList = ...;
result = entityList.stream() //
    .map(HogeHogeDto::new) //
    .sorted() //
    .collect(Collectors.toList());

どうなるほどと思ったかというと、これで entityList の中身が HogeHogeDto のコンストラクタ、具体的には HogeHogeDto(HogeHoge) を呼び出している点です。上記ソースコードでは HogeHogeDto::new としか書いていないのでどのコンストラクタを呼び出すかまでは明示していませんが、型推論が働いてちゃんと HogeHogeDto(HogeHoge) を呼び出してくれます。

検証

HogeHogeDto クラスに、引数に HogeHoge を取るコンストラクタと、デフォルトコンストラクタがあった場合、ちゃんと HogeHoge を取るコンストラクタが呼ばれるか?
:ok_hand:

追加検証

では、デフォルトコンストラクタの方を明示的に呼びたい(ストリームで渡されるものは無視したい)時はどうすればよいのでしょうか?
→明示的に無視する書き方をすることでできる。

検証コード

StreamMapTest.java
import java.util.List;
import java.util.ArrayList;

/**
 * Stream API 基礎トレーニング。
 * {@code map()} を使用した新しいリストの生成。
 */
public class StreamMapTest {
    /**
     * エントリポイント。
     * 変換前のリスト {@code List<Integer>} を元に、そのリストのサイズの分だけ
     * {@code StreamMapTest} のインスタンスを生成し、それぞれに所定の処理を行う。
     *
     * @param arguments 使用しない
     */
    public static void main(String[] arguments) {
        // テスト用に使用する変換前のリスト。
        // ここでは、StreamTest#value が int 型なので、後で代入
        // しやすくするよう List の中身は Integer としている。
        // なお0はデフォルトコンストラクタで使用するため1から
        // 値を代入している。
        List<Integer> values = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            values.add(new Integer(i));
        }
        
        //以下確認テスト
        //(違いを見やすくするため個別のメソッドにせず
        // main()メソッド内に列挙している)
        
        // 1:intを引数に取るコンストラクタが呼ばれるパターン(1)
        System.out.println("test1------");
        values.stream() //
            .map(StreamMapTest::new) //
            .forEach(e -> System.out.println(e.getValue()));
        
        // 2:intを引数に取るコンストラクタが呼ばれるパターン(2)
        System.out.println("test2------");
        values.stream() //
            .map(e -> new StreamMapTest(e)) //
            .forEach(e -> System.out.println(e.getValue()));
        
        // 3:デフォルトコンストラクタが呼ばれるパターン
        System.out.println("test3------");
        values.stream() //
            .map(e -> new StreamMapTest()) //
            .forEach(e -> System.out.println(e.getValue()));
        
        // 4:コンパイルエラーになるパターン
        //System.out.println("test4------");
        //values.stream() //
        //    .map(new StreamMethodTest()) //
        //    .forEach(e -> System.out.println(e.getValue()));
    }
    
    /** どのようにインスタンスが作られたかをわかりやすくするために保持する値。 */
    private final int value;
    
    /**
     * デフォルトコンストラクタ。
     * インスタンス変数の値には0を設定している。
     */
    public StreamMapTest() {
        this(0);
    }
    
    /**
     * intの引数を1つ取るコンストラクタ。
     * 指定された値をインスタンス変数に代入している。
     *
     * @param value インスタンス変数に代入する値
     */
    public StreamMapTest(int value) {
        this.value = value;
    }
    
    /**
     * インスタンス変数の値を取得する。
     *
     * @return インスタンス変数の値
     */
    public int getValue() {
        return value;
    }
}

実行結果

C:\TEMP>java StreamMapTest
test1------
1
2
3
test2------
1
2
3
test3------
0
0
0

C:\TEMP>
3
4
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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?