[JAVA8] Stream


今日はJAVA 8で役立つstreamについてさらに知ります.

1.紹介


1-1. Streamはデータストアではありません。


基本的に、Streamはデータを含むリポジトリではありません.
データを含むリポジトリはList,Map,Arrayなどのオブジェクトを表す.
しかし、Streamは、あるものを格納するためのリポジトリではなく、データ処理のためのパイプラインと言える.

1-2. Streamはデータソースを変更しません。


データソースを変更しないとはどういう意味ですか?
コードで理解してみましょう.
List<String> list = new ArrayList<String>();

list.add("a");
list.add("b");
list.add("c");
list.add("d");

List<String> list2 = list.stream().map(c -> c.toUpperCase())
.collect(Collectors.toList());

list.forEach(System.out::println);	// a,b,c,d
list2.forEach(System.out::println); // A,B,C,D
リストの要素値をmap()で大文字に変換します.
ただし、これはlist 2にのみ含まれ、既存のlistの値は変更されません.これは、上記のデータソースを変更しないことを意味します.

1-3. 仲介製品は怠け者だ。

  • 仲介製品:Streamの製品
  • を返します.
  • 終了(=端末)製品:Streamオブジェクト以外の製品を返す
  • 仲介製品の種類は以下の通りである.
    filter, map, limit, skip, sorted, ...
    終了(=端末)操作のタイプは次のとおりです.
    collect, allMatch, forEach, ...
    怠惰とは何か.コードで確認してみましょう.
    List<String> list = new ArrayList<String>();
    
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    
    list.stream()
    	.map(s -> {
        		System.out.println(s.toUpperCase()); 
                	return s.toUpperCase();
    	});
    
    list.forEach(System.out::println);	// a,b,c,d
    実行すると、一番下のsoutのみが実行されていることがわかります.
    理由は上記の通りです.
    map()は仲介操作であり、終了操作に遭遇するまで実行されません.
    ただし、終了操作は存在しないため、実行されていません.

    1-5. 並列処理が可能です。


    膨大なデータを扱う場合、複数のスレッドを自動的に分割する機能があります.
    ParallelStream()です.
    使用方法は、以前stream()で記録していた部分をparallelStream()に変更することです.
    List<String> list = new ArrayList<String>();
    
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    
    list.ParallerStream()
    	.map(s -> {
    		System.out.println(Thread.currentThread().getName()); 
    		return s.toUpperCase();
    	})
    	.collect(Collectors.toList());
    前述したように、既存のstream()を使用すると、MainThreadでのみ処理されているすべてのコンテンツが別のThreadで処理されていることがわかります.
    しかし、盲目的に並列に処理するべきではない.
    並列処理を行うためには,threadを生成するコスト,切り替えのコストなどが存在する可能性があり,逆に悪影響を及ぼすためである.
    したがって,膨大な量を扱う場合にのみ,自分で判断して用いることが有効である.