본문 바로가기
JAVA

[JAVA] - Stream API 이해 6

by nam_ji 2024. 5. 31.

StreamAPI

스트림 생성

1. 빈 스트림 생성

  • Stream::empty는 빈 스트림을 생성합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------빈 스트림 생성------------------");
        EmptyStream emptyStream = new EmptyStream();
        emptyStream.emptyStream();
      }
    }
    
    class EmptyStream {
      public void emptyStream () {
        Stream<String> emptyStream = Stream.empty();
    
        System.out.println("빈 스트림 : " + emptyStream.collect(Collectors.toList()));
      }
    }
    
    /*
    출력
    ------------------빈 스트림 생성------------------
    빈 스트림 : []
    */

2. 매개변수를 이용한 생성

  • Stream::of는 매개변수 목록을 받고 Arrays.stream을 반환하여 스트림을 생성합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------매개변수로 스트림 생성------------------");
        ParameterStream parameterStream = new ParameterStream();
        parameterStream.parameterStream();
      }
    }
    
    class ParameterStream {
      public void parameterStream () {
        Stream<Integer> parameterStream =
            Stream.of(1, 2, 3, 4, 5);
    
        System.out.println("매개변수를 이용한 스트림 생성 : " + parameterStream.collect(Collectors.toList()));
      }
    }
    
    /*
    출력
    ------------------매개변수로 스트림 생성------------------
    매개변수를 이용한 스트림 생성 : [1, 2, 3, 4, 5]
    */

3. null이 될 수도 있는 객체를 스트림화

  • 자바 9 이상에서 추가된 Stream::ofNullable은 매개변수 값이 null이 아니면 스트림을 생성합니다.
  • null인 경우 Stream::empty를 반환하여 빈 스트림을 생성합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------null이 될 수 있는 개체 스트림화------------------");
        NullStream nullStream = new NullStream();
        nullStream.nullStream();
      }
    }
    
    class NullStream {
      public void nullStream () {
        Map<String, List<Integer>> map = new HashMap<>();
        map.put("한자리", Arrays.asList(1, 2, 3, 4, 5));
        map.put("두자리", Arrays.asList(10));
        map.put("세자리", Arrays.asList(100, 200, 300));
    
        Stream<String> searchNum =
            Stream.ofNullable(map.get("한자리").stream()
                .map(Object::toString)
                .collect(Collectors.joining()));
    
        System.out.println("null이 아닌 객체 스트림화 : " + searchNum.collect(Collectors.toList()));
    
        Stream<String> searchNumber = Stream.ofNullable(map.get("네자리"))
            .flatMap(list -> Stream.of(list.stream()
                .map(Object::toString)
                .collect(Collectors.joining())));
    
        System.out.println("null인 객체 스트림화 : " + searchNumber.collect(Collectors.toList()));
      }
    }
    
    /*
    출력
    ------------------null이 될 수 있는 개체 스트림화------------------
    null이 아닌 객체 스트림화 : [12345]
    null인 객체 스트림화 : []
    */

4. 배열로 스트림 생성

  • Arrays.stream은 배열을 매개변수로 받아서 스트림을 생성합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------배열로 스트림 생성------------------");
        ArrayStream arrayStream = new ArrayStream();
        arrayStream.arrayStream();
      }
    }
    
    class ArrayStream {
      public void arrayStream () {
        int[] num = {1, 2, 3, 4, 5};
    
        IntStream intStream = Arrays.stream(num); // intStream 생성
    
        Stream<Integer> numStream = intStream.boxed(); // Stream<Integer>로 변환
    
        System.out.println(numStream.collect(Collectors.toList()));
      }
    }
    
    /*
    출력
    ------------------배열로 스트림 생성------------------
    [1, 2, 3, 4, 5]
    */

5. 파일로 스트림 생성

  • File::lines는 파일을 읽어 행을 하나의 String으로 간주하는 스트림을 생성합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------파일로 스트림 생성------------------");
        FileStream fileStream = new FileStream();
        fileStream.fileStream();
      }
    }
    
    class FileStream {
      public void fileStream () {
        Stream<String> fileStream = new BufferedReader(new InputStreamReader(
            Objects.requireNonNull(getClass().getResourceAsStream("/streamTest.txt"))))
            .lines();
    
        fileStream
            .flatMap(line -> Stream.of(line.split(" ")))
            .forEach(System.out::println);
      }
    }
    
    /*
    출력
    ------------------파일로 스트림 생성------------------
    스트림
    테스트
    파일
    스트림
    테스트
    파일로
    스트림
    생성
    파일로
    스트림
    생성
    테스트
    */
  • streamTest.txt는 resources 폴더에 담겨 있고 파일 안에는 출력과 같은 내용이 담겨 있습니다.

함수형 인터페이스로 스트림 생성

  • Stream::iterate와 Stream:generate는 함수형 인터페이스를 매개변수로 받아 무한 스트림을 생성할 수 있습니다.

1. iterate

  • iterate는 for문과 비슷한 구조를 갖습니다.
  • 매개변수는 초기값, Predicate<T>, UnaryOperator<T>를 사용합니다.
  • Predicate<T>는 선택사항이기 때문에 없어도 동작합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------함수형 인터페이스 스트림 생성------------------");
        IterateStream iterateStream = new IterateStream();
        iterateStream.interateStream();
      }
    }
    
    class IterateStream {
      public void interateStream () {
        System.out.println("초기값, 조건 형식의 iterate");
        Stream.iterate(0, n -> n + 1)
            .limit(5)
            .forEach(System.out::print);
    
        System.out.println("\n초기값, 조건, 조건 형식의 iterate");
        Stream.iterate(0, n -> n < 5, n -> n + 1)
            .forEach(System.out::print);
      }
    }
    
    /*
    출력
    ------------------함수형 인터페이스 스트림 생성------------------
    초기값, 조건 형식의 iterate
    01234
    초기값, 조건, 조건 형식의 iterate
    01234
    */

2. generate

  • 매개변수로 Supplier<T>만 받기 때문에 스트림 생성 시 별도의 인수가 필요없는 경우에만 사용합니다.
  • 사용 예시
    더보기
    더보기
    package lambdaExample;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.lang.reflect.Parameter;
    import java.nio.charset.Charset;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.security.Principal;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    public class CreateStream {
    
      public static void main(String[] args) {
        System.out.println("\n------------------함수형 인터페이스 스트림 생성2------------------");
        GenerateStream generateStream = new GenerateStream();
        generateStream.generateStream();
      }
    }
    
    class GenerateStream {
      public void generateStream () {
        Random random = new Random();
    
        System.out.println("generate를 이용해 로또 번호 생성해보기");
        IntStream.generate(() -> random.nextInt(45) + 1)
            .limit(6)
            .forEach(System.out::println);
      }
    }
    
    /*
    출력
    ------------------함수형 인터페이스 스트림 생성2------------------
    generate를 이용해 로또 번호 생성해보기
    43
    14
    30
    28
    26
    37
    */

최종 코드

더보기
더보기
package lambdaExample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Parameter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class CreateStream {

  public static void main(String[] args) {
    System.out.println("\n------------------빈 스트림 생성------------------");
    EmptyStream emptyStream = new EmptyStream();
    emptyStream.emptyStream();

    System.out.println("\n------------------매개변수로 스트림 생성------------------");
    ParameterStream parameterStream = new ParameterStream();
    parameterStream.parameterStream();

    System.out.println("\n------------------null이 될 수 있는 개체 스트림화------------------");
    NullStream nullStream = new NullStream();
    nullStream.nullStream();

    System.out.println("\n------------------배열로 스트림 생성------------------");
    ArrayStream arrayStream = new ArrayStream();
    arrayStream.arrayStream();

    System.out.println("\n------------------파일로 스트림 생성------------------");
    FileStream fileStream = new FileStream();
    fileStream.fileStream();

    System.out.println("\n------------------함수형 인터페이스 스트림 생성------------------");
    IterateStream iterateStream = new IterateStream();
    iterateStream.interateStream();

    System.out.println("\n------------------함수형 인터페이스 스트림 생성2------------------");
    GenerateStream generateStream = new GenerateStream();
    generateStream.generateStream();
  }
}

class GenerateStream {
  public void generateStream () {
    Random random = new Random();

    System.out.println("generate를 이용해 로또 번호 생성해보기");
    IntStream.generate(() -> random.nextInt(45) + 1)
        .limit(6)
        .forEach(System.out::println);
  }
}

class IterateStream {
  public void interateStream () {
    System.out.println("초기값, 조건 형식의 iterate");
    Stream.iterate(0, n -> n + 1)
        .limit(5)
        .forEach(System.out::print);

    System.out.println("\n초기값, 조건, 조건 형식의 iterate");
    Stream.iterate(0, n -> n < 5, n -> n + 1)
        .forEach(System.out::print);
  }
}

class FileStream {
  public void fileStream () {
    Stream<String> fileStream = new BufferedReader(new InputStreamReader(
        Objects.requireNonNull(getClass().getResourceAsStream("/streamTest.txt"))))
        .lines();

    fileStream
        .flatMap(line -> Stream.of(line.split(" ")))
        .forEach(System.out::println);
  }
}

class ArrayStream {
  public void arrayStream () {
    int[] num = {1, 2, 3, 4, 5};

    IntStream intStream = Arrays.stream(num); // intStream 생성

    Stream<Integer> numStream = intStream.boxed(); // Stream<Integer>로 변환

    System.out.println(numStream.collect(Collectors.toList()));
  }
}

class NullStream {
  public void nullStream () {
    Map<String, List<Integer>> map = new HashMap<>();
    map.put("한자리", Arrays.asList(1, 2, 3, 4, 5));
    map.put("두자리", Arrays.asList(10));
    map.put("세자리", Arrays.asList(100, 200, 300));

    Stream<String> searchNum =
        Stream.ofNullable(map.get("한자리").stream()
            .map(Object::toString)
            .collect(Collectors.joining()));

    System.out.println("null이 아닌 객체 스트림화 : " + searchNum.collect(Collectors.toList()));

    Stream<String> searchNumber = Stream.ofNullable(map.get("네자리"))
        .flatMap(list -> Stream.of(list.stream()
            .map(Object::toString)
            .collect(Collectors.joining())));

    System.out.println("null인 객체 스트림화 : " + searchNumber.collect(Collectors.toList()));
  }
}

class ParameterStream {
  public void parameterStream () {
    Stream<Integer> parameterStream =
        Stream.of(1, 2, 3, 4, 5);

    System.out.println("매개변수를 이용한 스트림 생성 : " + parameterStream.collect(Collectors.toList()));
  }
}

class EmptyStream {
  public void emptyStream () {
    Stream<String> emptyStream = Stream.empty();

    System.out.println("빈 스트림 : " + emptyStream.collect(Collectors.toList()));
  }
}

/*
출력
------------------빈 스트림 생성------------------
빈 스트림 : []

------------------매개변수로 스트림 생성------------------
매개변수를 이용한 스트림 생성 : [1, 2, 3, 4, 5]

------------------null이 될 수 있는 개체 스트림화------------------
null이 아닌 객체 스트림화 : [12345]
null인 객체 스트림화 : []

------------------배열로 스트림 생성------------------
[1, 2, 3, 4, 5]

------------------파일로 스트림 생성------------------
스트림
테스트
파일
스트림
테스트
파일로
스트림
생성
파일로
스트림
생성
테스트

------------------함수형 인터페이스 스트림 생성------------------
초기값, 조건 형식의 iterate
01234
초기값, 조건, 조건 형식의 iterate
01234
------------------함수형 인터페이스 스트림 생성2------------------
generate를 이용해 로또 번호 생성해보기
12
38
36
11
17
13
*/