728x90
JAVA Stream
java에서 제일 큰 분기점, 큰 변화가 있던 버전이라고 하는 java 8에서 추가된 기능으로, 람다식을 활용할 수 있게 해주는 기술이다. java 8 버전 이전에는 배열을 다루는 방법이 for문, 혹은 foreach문을 통해서 요소의 전부를 탐색하는 방법 밖에 없었다.
이러한 부분은 로직이 복잡해질수록 컨트롤하기 어렵고, 코드의 양이 많아지고, 여러 루프가 반복되며 효율이 떨어지기 마련이었다.
스트림은 배열, 컬렉션 인스턴스에 여러 함수를 조합하여 원하는 결과를 표현할 수 있다. 람다를 이용해 코드의 양을 줄이고, 간결하게 표현할 수 있다. 또한 하나의 작업을 두개 이상 작업으로 잘게 나누어 동시에 처리가 가능한 비동기처리 (병렬처리)가 가능하다.
String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);
Stream<String> streamOfArrayPart =
Arrays.stream(arr, 1, 3); // 1~2 요소 [b, c]
- 스트림은 배열, 혹은 컬렉션 인스턴스를 생성한 후에 위 코드와 같이 stream을 선언하여 생성할 수 있다.
스트림은 여러가지 함수를 지원하고, 배열, 컬렉션 인스턴스의 컨트롤을 쉽게 도와준다.
- Stream.builder()
- builder()를 사용하면 stream에 직접적으로 원하는 값을 넣을 수 있다. 사용법은 아래 코드와 같다.
Stream<String> builderStream = Stream.**<String>builder()** .add("Eric").add("Elena").add("Java") .build(); // [Eric, Elena, Java]
- Stream.iterate()
- iterate를 사용하면 초기값과 해당 값을 다루는 람다를 이용해 stream에 들어갈 요소를 만든다. 아래 코드와 같은 경우네는 30으로 시작하고, 2씩 증가되는 값들이 stream 배열요소로 들어가게 된다. stream같은 경우 사이즈를 정해주지 않으면 계속해서 들어가게된다.
Stream<Integer> iteratedStream = Stream.iterate(30, n -> n + 2).limit(5); // [30, 32, 34, 36, 38]
- Stream.concat(a,b)
- concat을 사용하면 두 개의 stream을 연결하여 새로운 stream을 생성할 수 있다. 아래의 코드처럼 두 stream을 연결하게된다.
Stream<String> stream1 = Stream.of("Java", "Scala", "Groovy"); Stream<String> stream2 = Stream.of("Python", "Go", "Swift"); Stream<String> concat = Stream.concat(stream1, stream2); // [Java, Scala, Groovy, Python, Go, Swift]
생성과 관련한 함수들은 대략적으로 위와같이 있고, 가공하기 위한 함수들도 여러 기능을 제공한다. 그 중 대표적으로 자주 사용되는 몇가지는 filter, mapping, sorting, Iterating 등이 존재한다.
- filter는 stream 내 요소들을 하나씩 체크하여 걸러내는 작업을 수행한다. Predicate 인자를 받는데 이곳에는 boolean을 리턴하는 함수형 인터페이스가 들어가게 된다.
- 간단한 예제로, stream에 대한 각 요소에 대한 평가식을 진행하여 a가 들어간 name만 반환된다.
- Stream<String> stream = names.stream() .filter(name -> name.contains("a")); // [Elena, Java]
- map은 stream 내부 요소들을 하나씩 특정 값으로 변환하는데, 이 때 값을 변환하기 위한 람다를 인자로 받게된다. stream에 들어가 있는 값이 인자로 들어가고, 로직을 진행후 반환되어 새로운 stream이 담기게 된다.
- stream 내부의 String의 toUpperCase 메소드를 실행하여 대문자로 변환된 값들이 담긴 stream을 반환하게 된다.
- Stream<String> stream = names.stream() .map(String::toUpperCase); // [ERIC, ELENA, JAVA]
- sorted는 다른 정렬들과 마찬가지로 Comparator를 이용해서 실행된다. compare 메소드는 두 인자를 비교해서 값을 리턴하는 기본 기능이다.
- // 인자를 받지 않는 경우 IntStream.of(14, 11, 20, 39, 23) .sorted() .boxed() .collect(Collectors.toList()); // [11, 14, 20, 23, 39] // 인자를 받는 경우 List<String> lang = Arrays.asList("Java", "Scala", "Groovy", "Python", "Go", "Swift"); lang.stream() .sorted() .collect(Collectors.toList()); // [Go, Groovy, Java, Python, Scala, Swift] lang.stream() .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); // [Swift, Scala, Python, Java, Groovy, Go]
- peek은 stream 내 요소들 각각을 대상으로 특정한 연산을 수행하는 메소드이다. 특정 결과를 반환하지 않는 함수형 인터페이스를 인자로 받게된다. 그렇기 때문에 stream 내 각각 요소들에 대한 특정 작업을 수행하지만 결과에 영향은 미치지 않는다.
728x90
'SpringBoot > Java' 카테고리의 다른 글
JAVA 고유 식별자 UUID (C# GUID) (0) | 2023.07.11 |
---|---|
java 백엔드 개발자 면접 질문 (1) (0) | 2023.06.15 |
Java - Spring // Stream, Assertions (0) | 2022.12.16 |
22.11.17 Java 백준 1110번 더하기 사이클 (0) | 2022.11.17 |
22.11.09 Java (0) | 2022.11.10 |