Java Stream API
๐ฌ Java Stream API๋ ๋ฌด์์ธ๊ฐ์?
โ (์ ๋ฆฌ ์ค)
Stream API๋?
๐ ๋ฐ์ดํฐ๋ฅผ ์ถ์ํํ๊ณ , ์ฒ๋ฆฌํ๋๋ฐ ์์ฃผ ์ฌ์ฉ๋๋ ํจ์๋ฅผ ์ ์ํด ๋ ๊ฒ.
JAVA
JAVA๋ ๊ฐ์ฒด์งํฅ ์ธ์ด์ด๊ธฐ ๋๋ฌธ์, ๊ธฐ๋ณธ์ ์ผ๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด ๋ถ๊ฐ๋ฅํ๋ค. ํ์ง๋ง JAVA8๋ถํฐ Stream API์ ๋๋ค์, ํจ์ํ ์ธํฐํ์ด์ค ๋ฑ์ ์ง์ํ๋ฉด์ JAVA๋ฅผ ์ง์ํจ์ผ๋ก์จ ํจ์ํ์ผ๋ก ํ๋ก๊ทธ๋๋ฐ์ ํ ์ ์๋ API๋ค์ ์ง์ํด์ฃผ๊ณ ์๋ค. ๊ทธ์ค์์ Stream API๋ ์์ ์ค๋ช ํ๋ฏ์ด ๋ฐ์ดํฐ๋ฅผ ์ถ์ํํ๊ณ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
์ฆ, ๋ฐ์ดํฐ์ ์ข ๋ฅ์ ์๊ด์์ด ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ฉฐ, ๊ทธ์ ๋ฐ๋ผ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ผ ์ ์๋ค.
์์ ์ฝ๋
- Stream ํ์ฉ ์ : ์๋ณธ์ ๋ฐ์ดํฐ๊ฐ ์ง์ ์ ๋ ฌ๋จ
String[] nameArr = {"yana", "winston", "daijee"};
List<String> nameList = Arrays.asList(nameArr);
//์๋ณธ์ ๋ฐ์ดํฐ๊ฐ ์ง์ ์ ๋ ฌ๋จ
Arrays.sort(nameArr);
Collection.sort(nameList);
for (String str : nameArr) {
System.out.println(str);
}
for (String str : nameList) {
System.out.println(str);
}
- Stream ํ์ฉ ํ : ์๋ณธ์ ๋ฐ์ดํฐ๊ฐ ์๋ ๋ณ๋์ Stream์ ์์ฑํ๊ณ , ๋ณต์ฌ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ์ฌ ์ถ๋ ฅํจ.
- ๊ฐ๋ ์ฑ ์๊ฒ ์ ๋ฆฌ ๊ฐ๋ฅ
- ์๋ณธ์ ๋ฐ์ดํฐ์ ๋ณํ์ ๊ฐํ์ง ์์
- ์ผํ์ฉ์
- ๋ด๋ถ ๋ฐ๋ณต์ผ๋ก ์์ ์ ์ฒ๋ฆฌํจ
String[] nameArr = {"yana", "winston", "daysee"}
List<String> nameList = Arrays.asList(nameArr);
Stream<String> nameStream = nameList.stream();
Stream<String> arrayStream = Arrays.stream(nameArr);
nameStream.sorted().forEach(System.out::println);
arrayStream.sorted().forEach(System.out::println);
1. ์๋ณธ์ ๋ฐ์ดํฐ์ ๋ณํ์ ๊ฐํ์ง ์์
Stream API๋ ์๋ณธ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๋ ๊ฒ์ด ์๋ ๋จ์ํ ์กฐํ๋ง ํ๋ฉฐ, ๋ณ๋์ Stream์ ์์ฑํ์ฌ ์ ๋ ฌ์ด๋ ํํฐ๋ง ๋ฑ์ ์์ ์ ์ฒ๋ฆฌํ๋ค.
2. ์ผํ์ฉ
์์์ ๋ช ์ํ์๋ฏ์ด, Stream API๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ Stream์ ์์ฑํด ์ฌ์ฉํ๋๋ฐ ์ด๋ ์ผํ์ฉ์ด๋ฉฐ, ํ๋ฒ ์ฌ์ฉํ๋ฉด ์ฌ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ํ์์์๋ Stream์ ๋ค์ ์์ฑํด์ฃผ์ด์ผ ํ๋ค.
๋ง์ฝ ๋ซํ Stream์ ๋ค์ ์ฌ์ฉํ๋ค๋ฉด IllegalStateException์ด ๋ฐ์ํ๊ฒ ๋๋ค.
userStream.sorted().forEach(System.out::print);
// ์คํธ๋ฆผ์ด ์ด๋ฏธ ์ฌ์ฉ๋์ด ๋ซํ์ผ๋ฏ๋ก ์๋ฌ ๋ฐ์
int count = userStream.count();
// IllegalStateException ๋ฐ์
java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
at java.util.stream.ReferencePipeline.noneMatch(ReferencePipeline.java:459)
3. ๋ด๋ถ ๋ฐ๋ณต์ผ๋ก ์์ ์ ์ฒ๋ฆฌํจ
๊ธฐ์กด์๋ ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๊ธฐ ์ํด for๋ฌธ ํน์ while๋ฌธ ๋ฑ๊ณผ ๊ฐ์ ๋ฌธ๋ฒ์ ์ฌ์ฉํด์ผ ํ์ง๋ง, stream์์๋ ๋ฐ๋ณต ๋ฌธ๋ฒ์ ๋ฉ์๋ ๋ด๋ถ์ ๋ง๋ จํด ๋์๊ธฐ์ ๊ฐ๊ฒฐํ ์ฝ๋ ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
nameStream.forEach(System.out::println);
Stream API์ ์ฐ์ฐ ์ข ๋ฅ
๐ก Stream์ฐ์ฐ์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ช ๊ฐ์ง ๋จ๊ณ๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค.
Stream์ ๊ฒฝ์ฐ ์์์ ์ธ๊ธํ์๋ฏ์ด, ์๋ณธ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ์ง ์๊ณ Stream์ ์์ฑํด ๊ฐ๊ณตํ๊ธฐ ๋๋ฌธ์
- Stream์์ฑ์ ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ฉฐ
์ํ๋ ๋ฐ์ดํฐ๊ฐ ๋์ฌ ๋๊น์ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๋ - ์ค๊ฐ ์ฐ์ฐ : ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ์คํธ๋ฆผ์ธ ์ฐ์ฐ.(์ค๋ณต ๊ฐ๋ฅ)
๋ง์ง๋ง์ผ๋ก Stream์ผ๋ก ๋์ด์๋ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ์ํ๋ ํํ๋ก ๋ง๋ค๊ฑฐ๋, ์ํ๋ ์ฐ์ฐ์ ์งํํ๋ - ์ต์ข ์ฐ์ฐ : ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ Stream์ด ์๋ ์ฐ์ฐ.(์ค๋ณต ๋ถ๊ฐ๋ฅ → ์คํธ๋ฆผ ์ฌํ์ฉ์ด ๋ถ๊ฐํ๊ธฐ ๋๋ฌธ)
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
.stream() // ์์ฑํ๊ธฐ
.filter(s -> s.startsWith("c")) // ๊ฐ๊ณตํ๊ธฐ
.map(String::toUpperCase) // ๊ฐ๊ณตํ๊ธฐ
.sorted() // ๊ฐ๊ณตํ๊ธฐ
.count(); // ๊ฒฐ๊ณผ๋ง๋ค๊ธฐ
Stream ์ฐ์ฐ์ ์ข ๋ฅ
์ค๊ฐ ์ฐ์ฐ | ์ค๋ช |
Stream<T> distint() | ์ค๋ณต ์ ๊ฑฐ |
Stream<T> filter ( Predicate<T> predicate ) | ์กฐ๊ฑด์ ์ ๋ง๋ ์์ ์ ์ธ |
Stream<T> limit ( long maxSize) | ์คํธ๋ฆผ์ ์ผ๋ถ๋ฅผ ์๋ผ๋ |
Stream<T> skip ( long n ) | ์คํธ๋ฆผ์ ์ผ๋ถ๋ฅผ ๊ฑด๋๋ |
Stream<T> peek ( Consumer<T> action ) | ์คํธ๋ฆผ ์์์ ์์ ์ํ |
Stream<T> sorted ( ) Stream<T> sorted ( Comparator<T> comparator ) | ์คํธ๋ฆผ์ ์์ ์ ๋ ฌ |
Stream<R> map (Function<T,R> mapper ) DoubleStream mapToDouble ( ToDoubleFunction<T> mapper ) IntStream mapToInt ( ToIntFunction<T> mapper ) LongStream mapToLong ( ToLongFunction<T> mapper ) Stream<R> flatMap (Function<T,Stream<R>> mapper ) DoubleStream flatMapToDouble ( Function<T, DoubleStream> m ) IntStream flatMapToInt ( Function<T, IntStream> m ) LongStream flatMapToLong ( Function<T, LongStream> m ) |
์คํธ๋ฆผ์ ์์๋ฅผ ๋ณํ |
void forEach ( Consumer< ? super T> action ) void forEachOrdered ( Consumer< ? super T> action ) |
๊ฐ ์์์ ์ง์ ๋ ์์ ์ํ |
long count ( ) | |
Optional<T> max ( Comparator<? super T> comparator ) Optional<T> min ( Comparator<? super T> comparator ) |
|
Optional<T> findAny ( ) //์๋ฌด๊ฑฐ๋ Optional<T> findFirst ( ) //์ฒซ ๋ฒ์งธ ์์ | ์คํธ๋ฆผ ์์ 1๊ฐ ๋ฐํ |
boolean allMatch ( Predicate<T> p ) //๋ชจ๋ boolean anyMatch ( Predicate<T> p ) //ํ๋๋ผ๋ boolean noneMatch ( Predicate<T> p ) //๋ชจ๋ ๋ง์กฑํ์ง ์์ |
์ฃผ์ด์ง ์กฐ๊ฑด ๋ง์กฑ์ฌ๋ถ ๋ฐํ |
Object[] toArray ( ) A[] toArray ( IntFunction<A[]> generator ) | ์คํธ๋ฆผ ๋ชจ๋ ์์ ๋ฐฐ์ด๋ก ๋ฐํ |
Optinal<T> reduce (BinaryOperator<T> accumulator ) T reduce (T identity, BinaryOperator<T> accumulator ) U reduce (U identity, BinaryOperator<U,T,U> accumulator, BinaryOperator<U> combiner ) |
์คํธ๋ฆผ ์์๋ฅผ ํ๋์ฉ ์ค์ฌ๊ฐ๋ฉฐ(๋ฆฌ๋์ฑ) ๊ณ์ฐ |
R collect (Collector<T,A,R> collector ) R collect (Supplier<R> supplier, BiConsumer<R,T> accumulator, BiConsumer<R,R> cimbiner ) |
์คํธ๋ฆผ ์์ ์์ง. ์์๋ฅผ ๊ทธ๋ฃนํ ํ๊ฑฐ๋, ๋ถํํ ๊ฒฐ๊ณผ๋ฅผ ์ปฌ๋ ์ ์ ๋ด์ ๋ฐํํ๋๋ฐ ์ฃผ๋ก ์ฌ์ฉ. |
์ง์ฐ๋ ์ฐ์ฐ
์คํธ๋ฆผ ์ฐ์ฐ์์, ์ต์ข ์ฐ์ฐ์ด ์ํ๋๊ธฐ ์ ๊น์ง๋ ์ค๊ฐ ์ฐ์ฐ์ด ์ํ๋์ง ์์. ์คํธ๋ฆผ์ ๋ํด distint() ๋ sort()์ ๊ฐ์ ์ค๊ฐ ์ฐ์ฐ์ ํธ์ถํด๋, ์ฆ๊ฐ์ ์ผ๋ก ์ฐ์ฐ์ด ์ํ๋๋ ๊ฒ์ด ์๋.
Stream <Integer>์ IntStream
์คํธ๋ฆผ์ ์์ ํ์ ์ T. ์ฆ Stream <T>. ์คํ ๋ฐ์ฑ & ์ธ๋ฐ์ฑ์ผ๋ก ์ธํ ๋นํจ์จ์ ์ค์ด๊ธฐ ์ํด ๋ฐ์ดํฐ ์์ค์ ์์๋ฅผ ๊ธฐ๋ณธํ์ผ๋ก IntStream, LongStream, DoubleStream์ด ์ ๊ณต๋จ. ๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก Stream <Integer>๋ณด๋ค Intstream์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํจ์จ์ . ( Intstream์ int ํ์ ์ ๊ฐ์ ์์ ํ๋๋ฐ ์ ์ฉํ ๋ฉ์๋๊ฐ ํฌํจ๋์๊ธฐ ๋๋ฌธ)
๋ณ๋ ฌ์ฒ๋ฆฌ ์คํธ๋ฆผ, ๋ณ๋ ฌ ์คํธ๋ฆผ
Stream์ parallel()์ด๋ผ๋ ๋ฉ์๋๋ฅผ ํธ์ถํด ๋ณ๋ ฌ๋ก ์ฐ์ฐ์ ์ํํ ์ ์์. ๋ฐ๋๋ก sequential()์ ํธ์ถํ๋ฉด ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌ๋์ง ์๊ฒ ์ค์ ํ ์ ์์(์ด๋ ๋ณ๋ ฌ์ฒ๋ฆฌ ํจ์ parallel()๋ฅผ ๋ฌดํจํํ๋ ๋ฐ์๋ง ์ฐ์.)
์คํธ๋ฆผ ์์ฑ
์ปฌ๋ ์
์ปฌ๋ ์ ์ ์ต๊ณ ์กฐ์์ธ Collection์ stream()์ด ์ ์๋์ด ์์. ๋ฐ๋ผ์ Collection์ ์์์ธ List์ Set์ ๊ตฌํํ ํด๋์ค๋ค์ ๋ชจ๋ ํด๋น ๋ฉ์๋๋ก ์คํธ๋ฆผ ์์ฑ ๊ฐ๋ฅ.
List<Integer> list = Arrays.asList (1,2,3,4,5); //๊ฐ๋ณ์ธ์
Stream<Integer> intStream = list.stream(); //list๋ฅผ ์์ค๋ก ํ๋ Stream ์์ฑ
intStream.forEach(System.out::println);
๋ฐฐ์ด
๋ฐฐ์ด์ ์์ค๋ก ํ๋ ์คํธ๋ฆผ์ ์์ฑํ๋ ๋ฉ์๋๋, Stream๊ณผ Arrays์ ์๋ static๋ฉ์๋๋ก ์ ์๋์ด ์์.
Stream<T> Stream.of(T... values)
Stream<T> Stream.of(T[])
Stream<T> Arrays.stream(T[])
Stream<T> Arrays.stream(T[] array, int startInclusive, int endExclusive)
๋ฐ๋ผ์ String Stream์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์๋ค.
Stream<String> strStream = Stream.of("a","b","c")
Stream<String> strStream = Stream.of(new String[] {"a","b","c"})
Stream<String> strStream = Arrays.stream(new String[] {"a","b","c"})
Stream<String> strStream = Arrays.stream(new String[] {"a","b","c"}, 0, 3)
์ฐธ๊ณ ์๋ฃ
'Web_Backend > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JAVA] ์ฌ๊ทํจ์ vs ๋ฐ๋ณต๋ฌธ (0) | 2023.06.20 |
---|---|
[JAVA] GC(Garbage collector, Garbage collection) (0) | 2023.06.15 |
[JAVA] String, String Builder, String buffer ์ฐจ์ด (0) | 2023.03.19 |
[์ด๋ณด ๊ฐ๋ฐ์์ ๋์ ๋ฆฌ๋ทฐ] "๊ณ์ ๋ผ๊ณ ์์ฃผ ์ฐพ์๋ณผ ์๋ฐ ๊ต๋ณด์ฌ" ์ฝ๋ฉ ๊ฐ๋ ์ก๋ ์๋ฐ ์ฝ๋ฉ ๋ฌธ์ ์ง (0) | 2022.12.02 |
[Java์ ์ ์] 08 ์์ธ์ฒ๋ฆฌ(Exception Handling) (0) | 2022.01.31 |
์ผ๋์ ์ฝ๋ฉ ์ผ๊ธฐ์ฅ :) #์ฝ๋ฉ๋ธ๋ก๊ทธ #๊ธฐ์ ๋ธ๋ก๊ทธ #์ฝ๋ฉ #์กฐ๊ธ์ฉ,๊พธ์คํ
ํฌ์คํ ์ด ์ข์๋ค๋ฉด "์ข์์โค๏ธ" ๋๋ "๊ตฌ๋ ๐๐ป" ํด์ฃผ์ธ์!