Java/스트림(Stream)

[Java]Stream 합치는 방법 - concat 메서드

DevStory 2022. 8. 26.

concat 메서드

Stream 클래스에서 제공하는 concat() 메서드는 두 개의 Stream을 전달받아 하나로 합쳐진 새로운 Stream을 반환합니다.

public static <T> Stream<T> concat(
  Stream<? extends T> a, 
  Stream<? extends T> b)

concat 메서드 특징

  • 첫 번째 매개변수인 a의 뒤에 두 번째 매개변수인 b의 요소를 추가합니다.
  • 스트림 중 하나라도 병렬인 경우 출력 스트림은 병렬입니다. 즉, 요소의 순서를 보장하지 않습니다.
  • 출력 스트림이 생성되면 두 입력 스트림에 대한 닫기 핸들러가 호출됩니다.

예제 1. 두 스트림을 합치기

다음 예제는 Integer 타입인 두 개의 List를 스트림으로 변환 후 합쳐진 새로운 스트림을 생성합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20, 30));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40, 50));

  Stream<Integer> intStream = 
          Stream.concat(intList1.stream(), intList2.stream());

  intStream.forEach(System.out::println);
}

[실행 결과]

10
20
30
30
40
50

예제 2. 두 스트림을 합친 후 정렬

다음 예제는 Integer 타입의 홀수 값이 존재하는 List와 짝수 값이 존재하는 LIst를 스트림으로 변환 후 concat() 메서드에 의해 생성된 스트림을 정렬합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(1, 3, 5));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(2, 4, 6));

  Stream<Integer> intStream1 = intList1.stream();
  Stream<Integer> intStream2 = intList2.stream();

  Stream<Integer> concatResultStream =
          Stream.concat(intStream1, intStream2).sorted();

  concatResultStream.forEach(System.out::println);
}

[실행 결과]

1
2
3
4
5
6

예제 3. 병렬 스트림 사용

다음 예제는 List 중 하나를 병렬 스트림으로 변환 후 concat() 메서드에 전달합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20, 30));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40, 50));
 
  Stream<Integer> intStream =
          Stream.concat(intList1.parallelStream(), intList2.stream());

  intStream.forEach(System.out::println);
}

[실행 결과]

30
50
10
30
40
20

실행 결과에서 확인할 수 있듯이 스트림 요소의 순서를 보장하지 않으며, 소스 코드를 다시 실행할 때마다 결과가 달라집니다.


예제 4. 두 스트림을 합친 후 중복 요소 제거

concat() 메서드는 중복 요소를 신경 쓰지 않습니다. 중복 요소를 제거하고 싶은 경우 concat() 메서드 뒤에 distinct() 메서드를 호출합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20, 30));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40, 50));

  Stream<Integer> intStream =
          Stream.concat(intList1.stream(), intList2.stream()).distinct();

  intStream.forEach(System.out::println);
}

[실행 결과]

10
20
30
40
50

예제 5. 세 개 이상의 스트림 합치기

concat() 메서드 내부에 concat() 메서드를 호출하여 세 개 이상의 스트림을 합칠 수 있습니다.

 

다음 예제는 Integer 타입인 네 개의 List를 스트림으로 변환 후 스트림이 병합된 새로운 스트림을 생성합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40));
  List<Integer> intList3 = new ArrayList<>(Arrays.asList(50, 60));
  List<Integer> intList4 = new ArrayList<>(Arrays.asList(70, 80));

  Stream<Integer> intStream1 = intList1.stream();
  Stream<Integer> intStream2 = intList2.stream();
  Stream<Integer> intStream3 = intList3.stream();
  Stream<Integer> intStream4 = intList4.stream();

  Stream<Integer> concatResultStream =
          Stream.concat(intStream1,
                  Stream.concat(intStream2,
                          Stream.concat(intStream3, intStream4)));

  concatResultStream.forEach(System.out::println);
}

[실행 결과]

10
20
30
40
50
60
70
80

예제 6. 닫기 핸들러 호출 후 스트림 접근하는 경우

concat() 메서드는 새로운 스트림을 반환하면, 매개변수로 전달된 입력 스트림을 닫습니다.

 

따라서, 닫힌 입력 스트림을 접근하면 IllegalStateException이 발생합니다.

 

다음 예제는 concat() 메서드 실행 종료 후 매개변수로 전달된 입력 스트림을 접근합니다.

public static void main(String args[]) {
  List<Integer> intList1 = new ArrayList<>(Arrays.asList(10, 20));
  List<Integer> intList2 = new ArrayList<>(Arrays.asList(30, 40));

  Stream<Integer> intStream1 = intList1.stream();
  Stream<Integer> intStream2 = intList2.stream();

  Stream<Integer> concatResultStream =
          Stream.concat(intStream1, intStream2);

  System.out.println("[concatResultStream의 요소 출력]");
  concatResultStream.forEach(System.out::println);

  System.out.println("[intStream1의 요소 출력]");
  intStream1.forEach(System.out::println);

  System.out.println("[intStream2의 요소 출력]");
  intStream2.forEach(System.out::println);
}

 [에러 내용]

반응형

댓글