注目記事

【Javaコード入門】Stream API_②Streamの生成

以下に、Streamを生成する基本的な方法をまとめます。

オブジェクトをStreamに変換する

リスト、文字列など、クラスによっては現在のインスタンスをもとにStreamを生成できます。以下に主なものをまとめます。

 

Streamに変換するための主なメソッド

メソッド Streamの対象
Colletion#stream() リスト/セットなどのコレクション
Colletion#parallelStream() リスト/セットなどのコレクション(並列化)
Arrays.stream(ary) 配列
String#chars() 文字群
String#codePoints() 文字群(サロゲートペア対応)
BufferedReader#lines() 各行
Files.lines(path, charset) ファイルの各行
Random.ints(begin, end) begin~endのint型乱数

たとえば以下は、Mapの内容をStream経由で列挙する例です。Mapはstreamメソッドを持たないので、一旦、entrySetメソッドでSetに変換してからStream化します。

StreamBasic2.java
  1. package com.example.mynavi.streamapi;
  2.  
  3. import java.util.Map;
  4.  
  5. public class StreamBasic2 {
  6.   public static void main(String args) {
  7.     var data = Map.of("dog", "", "cat", "", "hamster", "ハムスター");
  8.  
  9.     data.entrySet().stream()
  10.       .forEach(System.out::println);
  11.   }
  12. }

  1. hamster=ハムスター
  2. cat=猫
  3. dog=犬

引数から生成する – ofメソッド

public <T> Stream<T> of(T… values)
 T:要素の型
 values:要素の値(群)

ofメソッドを利用することで、指定された値(群)から新規のStreamを生成できます。

StreamOf.java
  1. ¥package com.example.mynavi.streamapi;
  2.  
  3. import java.util.stream.Stream;
  4.  
  5. public class StreamOf {
  6.   public static void main(String args) {
  7.     Stream.of("あいうえお", "かきくけこ", "さしすせそ")
  8.       .forEach(System.out::println);
  9.   }
  10. }

  1. あいうえお
  2. かきくけ
  3. さしすせそ

ラムダ式の戻り値から生成する – generateメソッド

public static <T> Stream<T> generate(Supplier<? extends T> s)
 T:要素の型
 s:要素生成のためのラムダ式

generateメソッドを利用することで、ラムダ式の戻り値をもとにStreamを生成できます。たとえば以下は、現在日時のタイムスタンプ値をストリーム化します。

StreamGen.java
  1. package com.example.mynavi.streamapi;
  2.  
  3. import java.util.Date;
  4. import java.util.stream.Stream;
  5.  
  6. public class StreamGen {
  7.   public static void main(String args) {
  8.     Stream
  9.       .generate(() -> {
  10.         try {
  11.           // ダミーの休止
  12.           Thread.sleep(300);
  13.         } catch (InterruptedException e) { }
  14.         return (new Date()).getTime();
  15.       })
  16.       .limit(10)
  17.       .forEach(System.out::println);
  18.   }
  19. }<

  1. 1736562990772
  2. 1736562991087
  3. 1736562991398
  4. 1736562991709
  5. 1736562992023
  6. 1736562992337
  7. 1736562992650
  8. 1736562992962
  9. 1736562993276
  10. 1736562993587

generateメソッドは無限ストリームを生成します。よって、ここではlimitメソッドで最初の10件でStreamを打ち切っています。

複数のStreamを結合する – concatメソッド

public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
 T:要素の型
 a、b:結合するStream

concatメソッドは既存のStreamをまとめ、一つのStreamに束ねます。

StreamConcat.java
  1. package com.example.mynavi.streamapi;
  2.  
  3. import java.util.stream.Stream;
  4.  
  5. public class StreamConcat {
  6.   public static void main(String args) {
  7.     var s1 = Stream.of("あいうえお", "かきくけこ");
  8.     var s2 = Stream.of("さしすせそ", "たちつてと");
  9.     Stream.concat(s1, s2)
  10.       .forEach(System.out::println);
  11.   }
  12. }

  1. あいうえお
  2. かきくけこ
  3. さしすせそ
  4. たちつてと

指定範囲のStreamを生成する – rangeメソッド

public static IntStream range(int start, int end)
 start:開始値
 end:終了値

IntStream/LongStream/DoubleStreamクラスのrangeメソッドを利用することで、start~endの範囲を持つStreamを生成できます。rangeメソッドの戻り値は、基本型(int/long/double)に対応したIntStream/LongStream/DoubleStreamです。

StreamInt.java
  1. package com.example.mynavi.streamapi;
  2.  
  3. import java.util.stream.IntStream;
  4.  
  5. public class StreamInt {
  6.   public static void main(String[] args) {
  7.     IntStream.range(5, 10)
  8.       .forEach(System.out::println);
  9.   }
  10. }

  1. 5
  2. 6
  3. 7
  4. 8
  5. 9

なお、IntStream/LongStream/DoubleStreamでも、一般的なStreamと同じく、of/generateなどのメソッドを利用できます。

Stream API_目次
Stream APIの基本
Streamの生成
Streamによる中間処理
Streamの終端処理

監修

山田祥寛(有限会社 WINGSプロジェクト)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NEC にてシステム企画業務に携わるが、2003年 4 月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト(https://wings.msn.to/)」の代表でもある。主な著書に『改訂 3 版JavaScript 本格入門』(技術評論社)、「独習シリーズ(C#・Python・PHP・Ruby・JSP&サーブレットなど)」(翔泳社)、「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravel など)」(Amazon Kindle)など。売り上げの累計は100万部を超える。