Stream
java 8 ์ด์ ์๋ ๋ฐฐ์ด ๋๋ ์ปฌ๋ ์ ์ ์ํํ๊ธฐ ์ํด for ๋๋ foreach๋ฌธ์ ๋๋ฉฐ ์์ ํ๋์ฉ ๊บผ๋ด์ ๋ค๋ฃจ์ด์ผ ํ๋ค.
stream์ ํ์ฉํ๋ฉด ๋ฐฐ์ด ๋๋ ์ปฌ๋ ์ ์ ํจ์ ์ฌ๋ฌ ๊ฐ๋ฅผ ์กฐํฉํด์ ํํฐ๋งํ๊ฑฐ๋ ๊ฐ๊ณตํ์ฌ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ผ๋ฉฐ, ๋๋ค๋ฅผ ์ด์ฉํด ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ํํํ ์ ์๋ค. ๋ํ ๋ด๋ถ ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋ณ๋ ฌ์ฒ๋ฆฌ๊ฐ ์ฝ๋ค.
- Stream์ ์๋ณธ ๋ฐ์ดํฐ ์์ฒด๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
- Stream์ ์ผํ์ฉ์ผ๋ก ์ฌ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
- Stream์ ๋ฐ๋ณต๋ฌธ์ ๋ด๋ถ์ ์จ๊ธฐ๋ ๋ด๋ถ ๋ฐ๋ณต์ผ๋ก ์ฒ๋ฆฌํ๋ค.
Stream ๊ตฌ์กฐ
๊ฐ์ฒด.์คํธ๋ฆผ์์ฑ().๊ฐ๊ณต().๊ฒฐ๊ณผ();
์ค๊ฐ ์ฐ์ฐ์ด ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ stream์ผ๋ก ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฐ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์์ฑ : ์คํธ๋ฆผ ์ธ์คํด์ค ์์ฑ
- ์ค๊ฐ ์ฐ์ฐ(๊ฐ๊ณตํ๊ธฐ) : filltering, mapping ๋ฑ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด๊ฐ๋ ์ค๊ฐ ์์
- ์ต์ข ์ฐ์ฐ(๊ฒฐ๊ณผ ๋ง๋ค๊ธฐ) : ์ต์ข ์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด๋ด๋ ์์
์คํธ๋ฆผ์ ๋ฐ์ดํฐ์ ํํฐ๋ง, ๋งคํ, ์ ๋ ฌ, ๊ทธ๋ฃนํ ๋ฑ์ ์ค๊ฐ์ฒ๋ฆฌ์ ํฉ๊ณ, ํ๊ท , ์นด์ดํ , ์ต๋๊ฐ, ์ต์๊ฐ ๋ฑ์ ์ต์ข ์ฒ๋ฆฌ๋ฅผ ํ์ดํ๋ผ์ธ์ผ๋ก ํด๊ฒฐํ๋ค.
๐ง ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ
ํ์ดํ๋ผ์ธ์ ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋จ๊ณ์ ์ถ๋ ฅ์ด ๋ค์ ๋จ๊ณ์ ์ ๋ ฅ์ผ๋ก ์ด์ด์ง๋ ํํ๋ก ์ฐ๊ฒฐ๋ ๊ตฌ์กฐ์ด๋ค.
์คํธ๋ฆผ์๋ ํํฐ๋ง, ๋งคํ, ์ ๋ ฌ ๋ฑ๊ณผ ๊ฐ์ ๋ง์ ์ค๊ฐ ์ฒ๋ฆฌ ๋ฉ์๋๊ฐ ์๋๋ฐ ์ด๋ค์ ์ค๊ฐ ์ฒ๋ฆฌ๋ ์คํธ๋ฆผ์ ๋ฆฌํดํ๋ค. ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์ง์ฐ ์ฐ์ฐ์ ์ํํ์ฌ ์ต์ข ์ฒ๋ฆฌ๊ฐ ์์๋๊ธฐ ์ ๊น์ง ์ค๊ฐ ์ฒ๋ฆฌ๋ ์ง์ฐ๋๋ค.
โ Stream ์์ฑ
์คํธ๋ฆผ์ ์ฌ์ฉํ ์ ์๋ ๋ฐ์ดํฐ ์์ค๋ ์๋์ ๊ฐ๋ค.
๋ฐ์ดํฐ ์์ค | ์ค๋ช |
์ปฌ๋ ์ | ์ปฌ๋ ์
์ ์กฐ์์ธ Collection ์ธํฐํ์ด์ค์ stream() ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ parallelStream() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ์คํธ๋ฆผ์ ์์ฑํ ์ ์์ |
๋ฐฐ์ด | Arrays ํด๋์ค์ stream() ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ ๊ธฐ๋ณธ ํ์ ์ธ int, long, double ํ์ ์ ์ฅํ ์ ์๋ ์คํธ๋ฆผ์ java.util.stream ํจํค์ง์ IntStream, LongStream, DoubleStream์ธํฐํ์ด์ค๋ก ์ ๊ณต๋จ |
๊ฐ๋ณ ๋งค๊ฐ๋ณ์ | Stream ํด๋์ค์ of() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ณ ๋งค๊ฐ๋ณ์๋ก ์คํธ๋ฆผ์ ์์ฑํ ์ ์์ |
์ง์ ๋ ๋ฒ์์ ์ฐ์๋ ์ ์ | IntStream์ด๋ LongStream ์ธํฐํ์ด์ค์๋ range()์ rangeClosed() ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ |
ํน์ ํ์ ์ ๋์๋ค | Random ํด๋์ค์๋ ints(), longs(), doubles()์ ๊ฐ์ ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ |
๋๋ค ํํ์ | Stream ํด๋์ค์ iterate()์ generate() ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ |
ํ์ผ | java.nio.file.Files ํด๋์ค์๋ lines() ๋ฉ์๋๊ฐ ์ ์๋์ด ์์ |
๋น ์คํธ๋ฆผ | ์๋ฌด ์์๋ ์๋ ์คํธ๋ฆผ์ Stream ํด๋์ค์ empty() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํ ์ ์์ |
// ์คํธ๋ฆผ ์์ฑ(์คํธ๋ฆผ ๋น๋)
Stream<String> builderStream = Stream.<String>builder().add("A").add("B").add("C").build(); // A, B, C
// ์ปฌ๋ ์
List<String> list1 = Arrays.asList("A", "B", "C");
Stream<String> stream1 = list1.stream();
stream1.forEach(System.out::println); // A, B, C
// ๋ฐฐ์ด
String[] arr1 = new String[]{"A", "B", "C"};
Stream<String> stream2 = Arrays.stream(arr1);
stream2.forEach(System.out::println); // A, B, C
Stream<String> stream3 = Arrays.stream(arr1, 1, 3);
stream3.forEach(System.out::println); // 1~2 ์์ A, B
// ๊ฐ๋ณ ๋งค๊ฐ๋ณ์
Stream<Integer> stream4 = Stream.of(1, 2, 3, 4, 5);
stream4.forEach(System.out::println); // 1, 2, 3, 4, 5
// ์ง์ ๋ ๋ฒ์์ ์ฐ์๋ ์ ์
IntStream intStream1 = IntStream.range(1, 5);
intStream1.forEach(x -> System.out.print(x + " ")); // 1 2 3 4
// ํน์ ํ์
์ ๋์
IntStream intStream2 = new Random().ints(4);
intStream2.forEach(System.out::println); // random int 4๊ฐ
// ๋๋ค ํํ์
// iterate(): ์ด๊ธฐ ๊ฐ๊ณผ ํด๋น ๊ฐ์ ๋ค๋ฃจ๋ ๋๋ค๋ฅผ ์ด์ฉํด ์คํธ๋ฆผ์ ๋ค์ด๊ฐ ์์๋ฅผ ๋ง๋ฆ
Stream<Integer> iteratedStream = Stream.iterate(1, n -> n + 1).limit(5); // [1, 2, 3, 4, 5]
// generate(): Supplier<T>์ ํด๋นํ๋ ๋๋ค๋ก ๊ฐ์ ๋ฃ์ ์ ์์
Stream<String> generatedStream = Stream.generate(() -> "new item").limit(5); // [el, el, el, el, el]
// ํ์ผ
Stream<String> lineStream = Files.lines(Paths.get("fileName.txt"), Charset.forName("UTF-8"));
// ๋น ์คํธ๋ฆผ
Stream<Object> stream5 = Stream.empty();
System.out.println(stream5.count()); // 0
// ๋ณ๋ ฌ ์คํธ๋ฆผ
Stream<String> parallelStream = Arrays.asList(new String[]{"A", "B", "C"}).parallelStream();
boolean isParallel = parallelStream.isParallel(); // ๋ณ๋ ฌ ์ฌ๋ถ ํ์ธ
parallelStream.map(x -> x + "-").anyMatch(y -> y == "A-"); // ๋ณ๋ ฌ๋ก ์ํ
โก ์ค๊ฐ ์ฐ์ฐ
์ฐ์ฐ | ๋ฉ์๋ |
ํํฐ๋ง | filter(), distinct() |
๋ณํ | map(), flatMap() |
์ ํ | limit(), skip() |
์ ๋ ฌ | sorted() |
์ฐ์ฐ ๊ฒฐ๊ณผ ํ์ธ | peek() |
// filter(): ์ธ์๋ก ๋ฐ๋ Predicate๋ boolean์ ๋ฆฌํดํ๋ ํจ์ํ ์ธํฐํ์ด์ค๊ฐ ๋ค์ด๊ฐ
List<String> list1 = Arrays.asList("Anna", "Erica", "Justin");
Stream<String> stream1 = list1.stream();
stream1.filter(n -> n.contains("a")).forEach(e -> System.out.print(e + " "); // Anna Erica
// distinct()
IntStream stream2 = IntStream.of(1, 2, 3, 3);
stream2.distinct().forEach(e -> System.out.print(e + " ")); // 1 2 3
// map()
Stream<String> stream3 = Stream.of("A", "B", "C");
stream3.map(String::toLowerCase).forEach(System.out::println)); // a, b, c
// flatMap(): ์ค์ฒฉ ๊ตฌ์กฐ๋ฅผ ํ ๋จ๊ณ ์ ๊ฑฐํ๊ณ ๋จ์ผ ์ปฌ๋ ์
์ผ๋ก ๋ง๋ค์ด์ค
List<List<String>> list2 = Arrays.asList(Arrays.asList("A"), Arrays.asList("B"));
System.out.println(list2.stream().flatMap(Collection::stream).collect(Collectors.toList())); // [A, B]
// skip(): ์ฒซ ๋ฒ์งธ ์์๋ถํฐ ์ ๋ฌ๋ ๊ฐ์๋งํผ์ ์ ์ธํ ๋๋จธ์ง ์์๋ง์ผ๋ก ์ด๋ฃจ์ด์ง ์๋ก์ด ์คํธ๋ฆผ
// limit(): ์ฒซ ๋ฒ์งธ ์์๋ถํฐ ์ ๋ฌ๋ ๊ฐ์๋งํผ์ ์์๋ง์ผ๋ก ์ด๋ฃจ์ด์ง ์๋ก์ด ์คํธ๋ฆผ
IntStream stream4 = IntStream.range(1, 10); // 1, 2, 3, 4, 5, 6, 7, 8, 9
stream4.skip(3).limit(3).forEach(System.out::println); // 4, 5, 6
// sorted()
// boxed(): int, long, double ์์๋ฅผ Integer, Long, Double ์์๋ก ๋ฐ์ฑ
IntStream.of(1, 3, 5, 4, 2).sorted().boxed().collect(Collectors.toList)); // [1, 2, 3, 4, 5]
IntStream.of(1, 3, 5, 4, 2).sorted(Comparator.reverseOrder()).boxed().collect(Collectors.toList)); // [5, 4, 3, 2, 1]
// peek(): ์คํธ๋ฆผ ๋ด ์์๋ค ๊ฐ๊ฐ์ ํน์ ์์
์ ์ํ
IntStream.of(1, 2, 3, 5, 4).peek(System.out::println).count(); // 1, 2, 3, 5, 4(๊ฒฐ๊ณผ๋ 5)
โข ์ต์ข ์ฐ์ฐ
์ฐ์ฐ | ๋ฉ์๋ |
์ถ๋ ฅ | forEach() |
์๋ชจ | reduce() |
๊ฒ์ | findFirst(), findAny() |
๊ฒ์ฌ | anyMatch(), allMatch(), noneMatch() |
ํต๊ณ | count(), min(), max() |
์ฐ์ฐ | sum(), average() |
์์ง | collect() |
// forEach()
Stream<String> stream1 = Stream.of("A", "B", "C");
stream1.forEach(System.out::println); // A, B, C
// reduce()
// - identity: ๊ณ์ฐ์ ์ํ ์ด๊ธฐ ๊ฐ
// - accumulator: ๊ฐ ์์๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณ์ฐ ๋ก์ง
// - combiner: ๋ณ๋ ฌ ์คํธ๋ฆผ์์ ๋๋ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ํ๋๋ก ํฉ์นจ
Stream<String> stream2 = Stream.of("A", "B", "C");
stream2.reduce(">>>", (a, b) -> a + "-" + b); // >>>A-B-C
// findFirst(): ๊ฐ์ฅ ์์ ์๋ ์์ ๋ฆฌํด
// findAny(): ๊ฐ์ฅ ๋จผ์ ์ฐพ์ ์์ ๋ฆฌํด(๋ณ๋ ฌ์ฒ๋ฆฌ์์ ์ฐจ์ด๊ฐ ์์)
IntStream stream3 = IntStream.of(1, 2, 3, 5, 4);
System.out.println(stream3.sorted().findFirst().getAsInt()); // 1, ์ ๋ ฌ ํ ์ฒซ ๋ฒ์งธ ์์ ๋ฆฌํด
// collect()
Stream<String> stream4 = Stream.of("B", "A", "C");
List<String> list = stream4.collect(Collectors.toList()); // ์คํธ๋ฆผ์ ๋ฆฌ์คํธ๋ก ๋ณํ, ["B", "A", "C"]
์ฐธ๊ณ ์๋ฃ ๋ฐ ์ถ์ฒ ๐โ๏ธ
https://ahndding.tistory.com/23
https://futurecreator.github.io/2018/08/26/java-8-streams/
'๊ฐ๋ฐ > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TCP ์์ผ ํต์ (0) | 2022.03.11 |
---|---|
Java ์ฐ์ ์์ ํ(Priority Queue) (0) | 2022.01.17 |
[JAVA 8] ํจ์ํ ์ธํฐํ์ด์ค(Functional Interface) (0) | 2022.01.14 |
[JAVA 8] ๋๋ค ํํ์ (0) | 2022.01.13 |
์๋ฐ Map ์์ฃผ ์ฐ๋ ๋ฉ์๋ ์ ๋ฆฌ (0) | 2021.11.02 |
๋๊ธ