Java ストリームでリストを操作する(Stream)

Javaのストリーム(Stream)でリストを操作するサンプルです。

目次

サンプル ストリーム (Stream)
  各要素の数をカウントする(count)
  各要素を処理する(map)
  各要素を条件で判定して抽出する(filter)
  1つめの要素を取得する(findFirst)
  リストを返す(collect+toList)
  要素の重複をなくす(distinct)
  要素を並び替える(sorted)
  要素の条件が全て一致するか(allMatch)
  要素の条件が1つでも一致するか(anyMatch)
  要素の条件が一致するものは1つもないか(noneMatch)
  並列に処理する(parallelStream/parallel)
  配列でストリームを使用する

ストリーム (Stream)

  • リストなどのコレクション、配列、ファイル、通信などに対して使用できます。
  • リスト等を指定してストリームを生成し、そのストリームに対して処理します。
  • 並列処理を行うこともできます。
  • 並列で処理ができるので値が変わらない変数のみアクセス可能です。
    →外部のローカル変数に対してアクセスできるのはfinal変数のみです。(再代入不可の変数)

コレクションでストリームを使用する

default Stream<E> stream()
  • コレクションでStreamのインスタンスを生成するにはCollectionインターフェースのstreamメソッドを使用します。
  • ArrayListなどのコレクションのクラスは、Collectionインターフェースを実装しているのでstreamメソッドを使用できます。
  • 以下は、OracleのJava8のCollectionクラスのstreamメソッドのリンクです。
    https://docs.oracle.com/javase/jp/8/docs/api/java/util/Collection.html#stream--

各要素の数をカウントする(count)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {

		List<String> c = new ArrayList<>(Arrays.asList("赤", "黄", "青"));

		long a = c.stream().count();
		System.out.println(a); // 3
	}
}

11行目は、ストリームでリストの数をカウントしています。

各要素を処理する(map)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {

		List<String> c = new ArrayList<>(Arrays.asList("赤", "黄", "青"));

        c.stream()
    		.map(a -> a + "です")
    		.forEach(System.out::println); //赤です 黄です 青です
	}
}

12行目は、mapメソッドで各要素を処理しています。

各要素を条件で判定して抽出する(filter)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {

		List<String> c = new ArrayList<>(Arrays.asList("aa", "ab", "ac"));

        c.stream()
    		.filter(a -> a.startsWith("ab"))
    		.forEach(System.out::println); //ab
	}
}

12行目は、filterメソッドで各要素を条件で判定してtrueのものを抽出しています。
startWithメソッドは、文字列の先頭が引数の値と一致した場合trueを返します。

1つめの要素を取得する(findFirst)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class Test1 {
	public static void main(String[] args) {

		List list1 = new ArrayList<>(Arrays.asList("赤", "黄", "青"));

		Optional list2 = list1.stream().findFirst();
		System.out.println(list2.get()); //赤
	}
}

12行目は、findFirstメソッドで1つめの要素を取得しています。

リストを返す(collect+toList)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Test1 {
	public static void main(String[] args) {

		List list1 = new ArrayList<>(Arrays.asList("aa", "ab", "ac"));

        List list2 = list1.stream()
        		.map(a -> a + "です")
        		.collect(Collectors.toList());
        System.out.println(list2); //[aaです, abです, acです]
	}
}

13行目は、collect+toListでリストを返します。

要素の重複をなくす(distinct)

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        
    	List<String> c = new ArrayList<>(Arrays.asList("A", "A", "B"));
        
        c.stream()
        	.distinct()
        	.forEach(System.out::println); //A B
    }
 }

12行目は、distinctメソッドで重複をなくしています。

要素を並び替える(sorted)

package test1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Test1 {
	public static void main(String[] args) {

		List<String> c = new ArrayList<>(Arrays.asList("aa", "zz", "cc"));

		c.stream()
			.sorted()
			.forEach(System.out::println); // aa cc zz

		c.stream()
			.sorted(Comparator.reverseOrder())
			.forEach(System.out::println); // zz cc aa
	}
}

14行目は、sortedメソッドに引数がありません。自然順序の昇順になります。
18行目は、sortedメソッドの引数にComparatorインターフェースのstaticメソッドのreverseOrderメソッドを指定しています。降順になります。自然順序の逆になります。

以下は、Java8のComparatorインターフェースのreverseOrderメソッドのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html#reverseOrder--

要素の条件が全て一致するか(allMatch)

boolean allMatch(Predicate<? super T> predicate);

allMatchメソッドは全て一致すればtrueを返します。

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        
    	List<Integer> num1 = new ArrayList<>(Arrays.asList(5,8,9));
        
        boolean a = num1.stream()
        		.allMatch(b -> b > 7); //すべての要素は7より大きいか
        System.out.println(a); //false
        
        boolean c = num1.stream()
        		.allMatch(d -> d > 3); //すべての要素は3より大きいか
        System.out.println(c); //true
    }
 }

12行目は、すべての要素は7より大きいか確認しています。→false
16行目は、すべての要素は3より大きいか確認しています。→true

要素の条件が1つでも一致するか(anyMatch)

boolean anyMatch(Predicate<? super T> predicate);

anyMatchメソッドは1つでも一致すればtrueを返します。

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        
    	List<Integer> num1 = new ArrayList<>(Arrays.asList(5,8,9));
        
        boolean a = num1.stream()
        		.anyMatch(b -> b > 10); //10より大きい要素はあるか
        System.out.println(a); //false
        
        boolean c = num1.stream()
        		.anyMatch(d -> d > 8); //8より大きい要素はあるか
        System.out.println(c); //true
    }
 }

12行目は、10より大きい要素はあるか確認しています。→false
16行目は、8より大きい要素はあるか確認しています。→true

要素の条件が一致するものは1つもないか(noneMatch)

boolean noneMatch(Predicate<? super T> predicate);

noneMatchメソッドは一致が1つもない場合にtrueを返します。

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        
    	List<Integer> num1 = new ArrayList<>(Arrays.asList(5,8,9));
        
        boolean a = num1.stream()
        		.noneMatch(b -> b > 7); //7より大きい要素はひとつもないか
        System.out.println(a); //false
        
        boolean c = num1.stream()
        		.noneMatch(d -> d > 10); //10より大きい要素はひとつもないか
        System.out.println(c); //true
    }
 }

12行目は、7より大きい要素はひとつもないか確認しています。→false
16行目は、10より大きい要素はひとつもないか確認しています。→true

並列に処理する(parallelStream/parallel)

コレクションを並列に処理するサンプルです。
parallelStreamメソッドまたはparallelメソッドを使用します。

package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        
        List<String> colors = new ArrayList<>(Arrays.asList("A","B","C","D"));
        
        colors.parallelStream()
        		.map(a -> a + "です")
        		.forEach(System.out::println); 
        		//Cです Dです Aです Bです

        colors.stream()
        		.parallel()
        		.map(a -> a + "です")
            	.forEach(System.out::println); 
        		//Cです Aです Bです Dです
    }
 }

要素が並列に処理されるので、返される値の順番は並び順ではありません。
11行目は、parallelStreamメソッドです。
17行目は、parallelメソッドです。

配列でストリームを使用する

public static <T> Stream<T> stream(T[] array)

配列でストリームを使用するサンプルです。

package test1;
import java.util.Arrays;

public class Test1 {
	public static void main(String[] args) {

		String[] arr = {"赤","黄","青"};

		long a = Arrays.stream(arr).count();
		System.out.println(a); // 3
	}
}

9行目は、ストリームで配列の数をカウントしています。

関連の記事

Java ラムダ式のサンプル
Java ラムダ式で関数型インターフェースを使用
Java ストリームで数値を合計する(IntStream)

△上に戻る