Stream 객체를 생성하는 다양한 방법

지인호·2021년 6월 9일
2

자바 Stream

목록 보기
2/4
post-thumbnail

Stream stream = new Stream?

🤔 스트림 객체는 어떻게 생성해야할까요?

이전 시간에는 스트림이 어떠한 기술이고 어떠한 때에 쓰이며 어떤 방식과 과정을 거쳐 사용되는지 알아보았습니다!
이번 시간에는 이러한 "스트림을 생성하는 다양한 방법" 을 알아보도록 하겠습니다!

배열을 스트림으로! Arrays.stream()

String[] arr = new String[] {"tomato", "banana", "watermelon"};
Stream<String> streamWasArray = Arrays.stream(arr);
Stream<String> streamWasArray2 = Arrays.stream(arr, 1, 2);
streamWasArray : "tomato", "banana", "watermelon"
streamWasArray2 : "banana", "watermelon"

Arrays 클래스의 stream 메서드는 배열을 통해 스트림을 생성해주는데요.
다음과같은 두가지 사용법으로 나뉩니다!

  • Arrays.stream(T[] arr);

    매개변수로 온 배열의 요소를 그대로 스트림으로 전환합니다.
  • Arrays.stream(T[] arr, int startInclusive, int endExclusive);

    매개변수로 온 배열의 요소를 startInclusive 번째 인덱스부터 endExclusive 인덱스까지만을 추출하여 스트림으로 전환합니다.

컬렉션을 스트림으로! Collection.stream()

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); //stream : "a", "b", "c"

컬렉션을 스트림으로 바꾸는 방법은 단순합니다. Collection 에 내장된 stream 메서드를 사용하면 됩니다!

텅 빈 스트림은 쓰고싶은데 Null은 싫다면? Empty Stream

public Stream<T> streamOf(List<T> list) {
	if(list == null || list.isEmpty()) return Stream.empty(); // stream : 
	else return list.stream();
}

다음과같은 상황에서, null 을 반환할경우, NullPointerException 같은 역겨운것들을 만날수도 있겠죠! 그래서 Stream 에선 Stream.empty() 라는 메서드를 통해 빈 스트림을 제공하고있습니다.

자기가 원하는 값을 직접 스트림에 넣어보자! Stream.builder()

Stream<String> builderStream = Stream.<String>builder()
	.add("java").add("python").add("c++").add("html is not programming lang")
    .build(); // builderStream : "java", "python", "c++", "html is not programming lang"

html 은 프로그래밍 언어가 아닙니다
Stream 은 builder 패턴을 통해 직접 생성할 수 있습니다.

변수가아닌 함수로 스트림을 만들어보자! Stream.generate()

Stream<String> generateStream = Stream.generate(() -> "looooop").limit(5)
//generateStream : "looooop", "looooop", "looooop", "looooop", "looooop"

generate 메서드를 사용하면 Supplier<T> 라는 함수형 인터페이스를 통한 람다로 값을 넣을 수 있습니다. 즉, 람다에서 리턴하는 값이 Stream 의 인자로 들어갑니다!
다만, generate 함수로는 인자를 몇개 넣을것인지 알 수 없으므로, generate() 가 반환하는 stream 에  limit 함수로 람다식을 총 몇번 실행시켜 인자로 넣을것인지를 정하여야합니다!

파이썬의 range 가 그리 편하다면서요? Stream.iterate()

Stream<Integer> iteratedStream = Stream.iterate(10, n -> n - 2).limit(5);
//iteratedStream = 10, 8, 6, 4, 2

list(range(10,20,2)).stream()
stream.iterate 를 활용하면 초기값과, 이전 인자값을 통해 스트림에 들어갈 요소를 만듭니다.
초기값이 n일때,

  • n을 먼저 stream 에 넣고
  • n 을 매개변수로 한 람다식을 처리하여, 반환된 값(n1) 을 stream 에 넣고
  • n1 을 매개변수로 한 람다식을 처리하여, 반환된 값(n2) 을 stream 에 넣고...
  • 이를 limit 함수에 명시된 횟수만큼 반복한다

라는 로직으로 실행되는것이죠!

Stream 클래스만 스트림이 아니다? 기본타입 스트림들!

Stream<Integer> 나 Stream<String> 같이 제너릭을 잘만 사용한다면 기본타입또한 스트림으로 구현할 수 있지만, 기본타입에 대한 더욱 강력한 기능들을 지원하는 또다른 클래스들이 있습니다!

  • IntStream, LongStream

    정수타입 인자를 받는 이 두 스트림은 range 와 rangeClosed 라는 매우 강력한 기능을 지원합니다!
	IntStream intStream = IntStream.range(1, 7); //intStream = 1, 2, 3, 4, 5, 6
	LongStream longStream = LongStream.rangeClosed(1, 7); //longStream = 1, 2, 3, 4, 5, 6, 7

range : 시작인덱스와 종료인덱스를 받아 시작인덱스부터 종료인덱스 이전 요소까지의 요소로 스트림을 만듭니다.
rangeClosed : 주 사용법은 range 와 같으나, rangeClosed 는 종료인덱스 또한 포함하여 스트림을 만듭니다.

  • FileStream

    java nio 에 내장된 Files 클래스의 lines 메소드로, 특정파일의 각 라인을 하나의 요소로 String 타입의 스트림을 만들 수 있습니다!
	Stream<String> fileStream = Files.lines(
    	Paths.get("stream.txt"), 
        StandardCharsets.UTF_8)
        );
  • 기본타입 스트림의 박싱

    저희는 int 형 변수를 Integer 객체로 형변환할때 이를 "박싱(boxing)" 이라 부릅니다!
    마찬가지로 IntStream 같은 기본 타입스트림들을 Stream<Integer> 같은 꼴로 변환시킬때 이것을 박싱이라 부르며, 기본타입스트림은 이를 boxed 라는 메서드를 통해 지원하고있습니다!
	Stream<Integer> boxedIntStream = IntStream.range(1, 5).boxed();

지금까지 스트림을 생성하는 다양한 방법에 대해 알아보았습니다!

적시 적소에 알맞은 방법으로 스트림을 생성한다면, 여러분의 코드는 더욱 높은 가독성을 띄울 수 있습니다! 예를들어, 1부터 100까지의 모든 자연수가있는 리스트가 필요하다면?

IntStream.rangeClosed(1, 100).boxed().collect(Collectors.toList());
//추후 배울 collect(Collectors.toList()) 는 스트림을 List 의 형태로 변형해주는 메서드입니다!

for 문으로 한다면 적어도 3줄이 되었을 문장이, 하나의 문장으로 해결이 되었습니다!
이렇게 편한 스트림! 꼭 써주실꺼죠? 😄
그럼 다음시간에 스트림의 가공법으로 다시 찾아뵙겠습니다!!

모두 건강조심하고 다음에 만나요~!!

profile
테오의 스프린트 17기 퍼실리테이터

2개의 댓글

comment-user-thumbnail
2021년 6월 10일

친절한 설명 감사합니다 :)
잘보고가요~

답글 달기
comment-user-thumbnail
2021년 6월 10일

마침 궁금하던 내용이였는데 친절한 설명 감사합니다

답글 달기