์ฝ๋๋ฅผ ์ง๋ค๋ณด๋ฉด ๊ฐ๋
์ฑ๊ณผ ๊ฐ๊ฒฐํจ์ ์ํด stream์ ์์ฃผ ์ฐ๊ฒ ๋๋ค.
ํ๋ฆฌ์ฝ์ค ๋ Stream์ ๋ํด ์ ๋ฆฌํ์์ผ๋,
๋ด๊ฐ ์ด ๊ธ์ ๋ฆฌํฉํ ๋ง(ใ
) ํด๋ณด๋ฉด์ ๋ค์ ๊ฐ๋
์ ์ตํ์ผ ๊ฒ ๋ค.
์คํธ๋ฆผ?
๋ฐฐ์ด ๋๋ ์ปฌ๋ ์ ์ธ์คํด์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด์ ํ์ดํ์ ํ๋ ค๋ณด๋ธ๋ค.
- ์ค๊ฐ ์ฐ์ฐ : ๋ง์ง๋ง์ด ์๋ ์์น์์ ์งํ์ด ๋์ด์ผ ํ๋ ์ฐ์ฐ
- ์ต์ข ์ฐ์ฐ : ๋ง์ง๋ง์ ์งํ์ด ๋์ด์ผ ํ๋ ์ฐ์ฐ ์คํธ๋ฆผ์ ์ค๊ฐ ์ฐ์ฐ๊ณผ ์ต์ข ์ฐ์ฐ์ ์งํํ๊ธฐ ์ข์ ๊ตฌ์กฐ๋ก ๋ฐฐ์น๋ ๋ณต์ฌ๋ณธ์ด๋ผ ํ ์ ์๋ค.
์คํธ๋ฆผ์ ํน์ฑ
๊ฐ๋ ์ฑ๊ณผ ๊ฐ๊ฒฐํจ
์ปฌ๋ ์ ์ด๋ ๋ฐฐ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ํด for๋ฌธ๊ณผ Iterator๋ฅผ ์ด์ฉํด ์์ฑํ ์ฝ๋๋ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ณ ์ฌ์ฌ์ฉ์ฑ๋ ๋จ์ด์ง๋ค.
๋ฐ์ดํฐ ์์ค ์ถ์ํ
์ด๋ค ๋ฉ์๋๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ฐ์ดํฐ ์์ค๋ง๋ค ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋ค๋ค์ผ ํ๋ ๋ฌธ์ ๋ฅผ
์คํธ๋ฆผ์ ํตํด ๋ฐ์ดํฐ ์์ค๊ฐ ๋ฌด์์ด๋ ๊ฐ์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ค๋ฃฐ ์ ์๊ฒ ๋์๋ค.
์ด๋ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๊ฐ์ ธ์จ๋ค.
Stream<String> listStream = strList.stream();
Stream<String> arrayStream = Arrays.stream(strArr);
listStream.sorted().forEach(System.out::println);
arrayStream.sorted().forEach(System.out::println);
๋ ์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ ์๋ก ๋ค๋ฅด์ง๋ง, ์ ๋ ฌํ๊ณ ์ถ๋ ฅํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋ค.
๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ก ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ๋ง ํ ๋ฟ,
๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
ํ์์์๋ง ์ ๋ ฌ๋ ๊ฒฐ๊ณผ๋ฅผ ์ปฌ๋ ์
์ด๋ ๋ฐฐ์ด์ ๋ด์์ ๋ฐํํ ์๋ ์๋ค.
List<String> sortedList = listStream.sorted().collect(Collections.toList());
์คํธ๋ฆผ์ ์ผํ์ฉ์ด๋ค.
Iterator์ฒ๋ผ ์ผํ์ฉ์ด๋ค. ํ๋ฒ ์ฌ์ฉํ๋ฉด ๋ซํ์ ๋ค์ ์ฌ์ฉํ ์ ์๋ค.
ํ์ํ๋ค๋ฉด ์คํธ๋ฆผ์ ๋ค์ ์์ฑํด์ผํ๋ค.
listStream.sorted().forEach(System.out::print);
int numOfElement = listStream.count(); //์๋ฌ- ์คํธ๋ฆผ์ด ์ด๋ฏธ ๋ซํ๋ค.
๋ด๋ถ ๋ฐ๋ณต
์คํธ๋ฆผ์ด ๊ฐ๊ฒฐํ ์ด์ ์ค ํ๋๊ฐ ๋ฐ๋ณต๋ฌธ์ ๋ฉ์๋ ๋ด๋ถ์ ์จ๊ธฐ๋ โ๋ด๋ถ ๋ฐ๋ณตโ ๋๋ถ์ด๋ค.
forEach()
๋ ์คํธ๋ฆผ์ ์ ์๋ ๋ฉ์๋ ์ค์ ํ๋๋ก ๋งค๊ฐ๋ณ์์ ๋์
๋
๋๋ค์์ ๋ฐ์ดํฐ ์์ค์ ๋ชจ๋ ์์์ ์ ์ฉํ๋ค.
stream.forEach(System.out::println);
์คํธ๋ฆผ ์์ฑํ๊ธฐ
์คํธ๋ฆผ์ ์์ฑ
๋ฉ์๋
์คํธ๋ฆผ ์์ฑ๊ณผ ๊ด๋ จํด Stream<T>
์ธํฐํ์ด์ค์ ์ ์๋์ด ์๋ static ๋ฉ์๋๋ ๋ ๊ฐ๊ฐ ์๋ค.
static <T> Stream<T>(T t)
static <T> Stream<T> of(T...values)
์ด ๋ฉ์๋์ ์คํธ๋ฆผ ์์ฑ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ธ์๋ก ์ง์ ์ ๋ฌํ ์ ์๋ค.
Example
class StreamOfStream {
public static void main(String[] args) {
// ex 1
Stream.of(11, 22, 33, 44)
.forEach(n -> System.out.print(n + "\t"));
System.out.println();
// ex 2
Stream.of("So Simple")
.forEach(s -> System.out.print(s + "\t"));
System.out.println();
// ex 3 ์ธ ๊ฐ์ ๋ฌธ์์ด๋ก ์ด๋ค์ง ์คํธ๋ฆผ์ด ์์ฑ๋๋ ๊ฒ์ด ์๋
// sl์ด ์ฐธ์กฐํ๋ ํ๋์ ์ธ์คํด์ค๋ง ์กด์ฌํ๋ค.
List<String> sl = Arrays.asList("Toy", "Robot", "Box");
Stream.of(sl)
.forEach(w -> System.out.print(w + "\t"));
System.out.println();
}
}
of ๋ฉ์๋์ ์ปฌ๋ ์
์ธ์คํด์ค๋ฅผ ์ ๋ฌํ๋ฉด ํด๋น ์ธ์คํด์ค ํ๋๋ก ์ด๋ค์ง ์คํธ๋ฆผ์ด ์์ฑ๋๋ค.
ํ์ง๋ง ๋ฐฐ์ด์ ์ ๋ฌํ๋ฉด ํ๋์ ๋ฐฐ์ด๋ก ์ด๋ค์ง ์คํธ๋ฆผ์ด ์์ฑ๋์ง ์๊ณ ,
๋ฐฐ์ด์ ์ ์ฅ๋ ์์๋ก ์ด๋ค์ง ์คํธ๋ฆผ์ด ์์ฑ๋๋ค.
๋ฐฐ์ด
๋ฐฐ์ด์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋์์ผ๋ก ์คํธ๋ฆผ์ ์์ฑํ ๋ ํธ์ถ๋๋ ๋ํ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
public satic <T> Stream<T> stream(T[] array) // Arrays ํด๋์ค์ ์ ์๋์ด ์๋ค
class StringStream {
public static void main(String[] args) {
String[] names = {"YOON", "LEE", "PARK"};
// ์คํธ๋ฆผ ์์ฑ
Stream<String> stm = Arrays.stream(names);
// ์ต์ข
์ฐ์ฐ ์งํ
stm.forEach(s -> System.out.println(s));
}
}
forEach๋ ์ต์ข
์ฐ์ฐ์ด๋ฉฐ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์ํ์ Consumer<T>
์ด๋ฏ๋ก ๋๋ค์์ ์ธ์๋ก ์ ๋ฌํด์ผํ๋ฉฐ,
๋ด๋ถ์ ์ผ๋ก ์คํธ๋ฆผ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ accept ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
์ปฌ๋ ์ ์ธ์คํด์ค
์ปฌ๋ ์ ์ธ์คํด์ค๋ฅผ ๋์์ผ๋ก ์คํธ๋ฆผ์ ์์ฑํ ๋ ํธ์ถ๋๋ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
default Stream<E> stream()
class ListStream {
public static void main(String[] args) {
List<String> list = Arrays.asList("Toy", "Robot", "Box");
list.stream()
.forEach(s -> System.out.print(s + "\t"));
System.out.println();
}
}
ํน์ ๋ฒ์์ ์ ์
IntStream
๊ณผ LongStream
์ ์ง์ ๋ ๋ฒ์์ ์ฐ์๋ ์ ์๋ฅผ ์คํธ๋ฆผ์ผ๋ก ์์ฑํด์
๋ฐํํ๋ range()
์ rangeClosed()
๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
IntStream intStream = IntStream.range(1, 5); // 1,2,3,4,
IntStream intStream = IntStream = Intstream.rangeClosed(1, 5); // 1,2,3,4,5
range
๋ end๊ฐ ๋ฒ์์ ํฌํจ๋์ง ์๊ณ rangeClosed
๋ ํฌํจ๋๋ค.
๋๋ค์ - iterate(), generate()
Stream ํด๋์ค์ iterate()
์ generate()
๋ ๋๋ค์์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์,
์ด ๋๋ค์์ ์ํด ๊ณ์ฐ๋๋ ๊ฐ๋ค์ ์์๋ก ํ๋ ๋ฌดํ ์คํธ๋ฆผ์ ์์ฑํ๋ค.
์ด๋ ์์ฑ๋๋ ์คํธ๋ฆผ์ ๋ฌดํํ๊ธฐ ๋๋ฌธ์ limit()
๋ฅผ ํธ์ถํ์ฌ ํน์ ์ฌ์ด์ฆ๋ก ์ ํํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
iterate()
Stream<Integer> evenStream = Stream.iterate(0, n -> n+2).limit(5);
// 0, 2, 4 ...
์จ๋๋ก ์ง์ ๋ ๊ฐ๋ถํฐ ์์ํด์, ๋๋ค์์ ์ํด ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ์๋ ๊ฐ์ผ๋ก ํด์ ๊ณ์ฐ์ ๋ฐ๋ณตํ๋ค.
generate()
Stream<Integer> randomStream = Stream.generate(Math::random).limit(5);
iterate()
์ฒ๋ผ ๋๋ค์์ ์ํด ๊ณ์ฐ๋๋ ๊ฐ์ ์์๋ก ํ๋ ๋ฌดํ ์คํธ๋ฆผ์ ์์ฑํด์
๋ฐํํ์ง๋ง, iterate()
์ ๋ฌ๋ฆฌ ์ด์ ๊ฒฐ๊ณผ๋ฅผ ์ด์ฉํด์ ๋ค์ ์์๋ฅผ ๊ณ์ฐํ์ง ์๋๋ค.
๋น ์คํธ๋ฆผ
์์๊ฐ ํ๋๋ ์๋ ๋น์ด์๋ ์คํธ๋ฆผ์ ์์ฑํ ์๋ ์๋ค.
์คํธ๋ฆผ์ ์ฐ์ฐ์ ์ํธํ ๊ฒฐ๊ณผ๊ฐ ํ๋๋ ์์ ๋, null๋ณด๋ค ๋น ์คํธ๋ฆผ์ ๋ฐํํ๋๊ฒ ๋ซ๋ค.
Stream emptyStream = Stream.empty(); // empty() ๋ ๋น ์คํธ๋ฆผ์ ์์ฑํด์ ๋ฐํํ๋ค.
long count = emptyStream.count(); // count๊ฐ์ 0
์ฌ๊ธฐ์ count()
๋ ์์์ ๊ฐฏ์๋ฅผ ๋ฐํํ๋ค.
์คํธ๋ฆผ์ ์ฐ์ฐ
์ง์ฐ ์ฒ๋ฆฌ
class MyFirstStream2 {
public static void main(String[] args) {
int[] ar = {1, 2, 3, 4, 5};
int sum = Arrays.stream(ar) // ์คํธ๋ฆผ์ ์์ฑ
.filter(n -> n%2 == 1) // filter ํต๊ณผ
.sum(); // sum์ ํต๊ณผ์์ผ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ
System.out.println(sum);
}
}
์ ์์ ์์ ์ฐ์ธ ๋ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
public static IntStream stream(int[] array)
IntStream filter(IntPredicate predicate)
filter์ sum ๋ฉ์๋๋ IntStream์ ์ธ์คํด์ค ๋ฉ์๋์ด๋ค.
์คํธ๋ฆผ์ ์ฐ์ฐ์ โ์ง์ฐ ์ฒ๋ฆฌโ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
์ต์ข
์ฐ์ฐ์ด ์ํ ๋๊ธฐ ์ ๊น์ง๋ ์ค๊ฐ ์ฐ์ฐ์ด ์ํ๋์ง ์๋๋ค.
์ ์์ ์์๋ sum์ด ํธ์ถ๋ ๋๊น์ง filter์ ํธ์ถ ๊ฒฐ๊ณผ๋ ์คํธ๋ฆผ์ ๋ฐ์๋์ง ์๋๋ค.
์ต์ข
์ฐ์ฐ์ธ sum์ด ํธ์ถ๋์ด์ผ๋ง filter์ ํธ์ถ ๊ฒฐ๊ณผ๊ฐ ์คํธ๋ฆผ์ ๋ฐ์๋๋ค.
์ด์ฒ๋ผ ์ต์ข
์ฐ์ฐ์ด ์๋ต๋๋ฉด ์ค๊ฐ ์ฐ์ฐ์ด ์๋ฏธ๊ฐ ์๋ค.
์คํธ๋ฆผ์ ์ค๊ฐ ์ฐ์ฐ
์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ์คํธ๋ฆผ์ธ ์ฐ์ฐ์ผ๋ก, ์คํธ๋ฆผ์ ์ฐ์ํด์ ์ค๊ฐ ์ฐ์ฐํ ์ ์๋ค.
filter (ํํฐ๋ง)
์คํธ๋ฆผ์ ๊ตฌ์ฑํ๋ ๋ฐ์ดํฐ ์ค ์ผ๋ถ๋ฅผ ์กฐ๊ฑด์ ๋ฐ๋ผ ๊ฑธ๋ฌ๋ด๋ ํ์๋ฅผ ์๋ฏธํ๋ค.
๋ฉ์๋
Stream<T> filter(Predicate<? super T> predicate) // Stream<T>์ ์กด์ฌ
๋งค๊ฐ๋ณ์ ํ์ด Predicate์ด๋ฏ๋ก test ๋ฉ์๋์ ๊ตฌํ์ ํด๋นํ๋ ๋๋ค์์
์ธ์๋ก ์ ๋ฌํด์ผ ํ๋ค.
๋ด๋ถ์ ์ผ๋ก ์คํธ๋ฆผ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ test๋ฅผ ํธ์ถํ๊ณ ,
๊ทธ ๊ฒฐ๊ณผ๊ฐ true์ด๋ฉด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆผ์ ๋จ๊ธด๋ค.
class FilterStream {
public static void main(String[] args) {
int[] ar = {1, 2, 3, 4, 5};
Arrays.stream(ar)
.filter(n -> n%2 == 1) // ํ์๋ง ํต๊ณผ
.forEach(n -> System.out.print(n + "\t"));
System.out.println();
List<String> sl = Arrays.asList("Toy", "Robot", "Box");
sl.stream()
.filter(s -> s.length() == 3) // ๊ธธ์ด๊ฐ 3์ด๋ฉด ํต๊ณผ
.forEach(s -> System.out.print(s + "\t"));
System.out.println();
}
}
map (๋งตํ)
์คํธ๋ฆผ ์์์์ ์ ์ฅ๋ ๊ฐ ์ค์์ ์ํ๋ ํ๋๋ง ๋ฝ์๋ด๊ฑฐ๋ ํน์ ํํ๋ก ๋ณํํด์ผ ํ ๋๊ฐ ์๋ค.
๋งตํ์ ์งํํ๋ฉด ์คํธ๋ฆผ์ ๋ฐ์ดํฐ ํ์ด ๋ฌ๋ผ์ง๋ ํน์ง์ด ์๋ค.
๋ฉ์๋
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
๋งค๊ฐ๋ณ์ ํ์ด Function์ด๋ฏ๋ก apply ๋ฉ์๋์ ๊ตฌํ์ ํด๋นํ๋ ๋๋ค์์
์ธ์๋ก ์ ๋ฌํด์ผ ํ๋ค.
๋ด๋ถ์ ์ผ๋ก ์คํธ๋ฆผ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ apply๋ฅผ ํธ์ถํ๊ณ ,
๊ทธ ๊ฒฐ๊ณผ๋ก ๋ฐํ๋๋ ๊ฐ์ ๋ชจ์ ์ ์คํธ๋ฆผ์ ์์ฑํ๋ค.
class MapToInt {
public static void main(String[] args) {
List<String> ls = Arrays.asList("Box", "Robot", "Simple");
ls.stream()
.map(s -> s.length())
.forEach(n -> System.out.print(n + "\t"));
System.out.println();
}
}
map vs flatMap
map์ ๋ฉ์๋
<R> Stream<R> map(Function<T, R> mapper)
map์ ์ ๋ฌํ ๋๋ค์์์๋ ์คํธ๋ฆผ์ ๊ตฌ์ฑํ ๋ฐ์ดํฐ๋ง ๋ฐํํ๋ฉด ๋๋ค.
flatMap์ ๋ฉ์๋
<R> Stream<R> flatMap(Function<T, Stream<R>> mapper)
flatMap์ ์ ๋ฌํ ๋๋ค์์์๋ ์คํธ๋ฆผ์ ์์ฑํ๊ณ ์ด๋ฅผ ๋ฐํํด์ผ ํ๋ค.
filter & map
example
int sum = ls.stream()
.filter(p -> p.getPrice() < 500)
.mapToInt(t -> t.getPrice())
.sum();
sorted
๋ฉ์๋
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> compatator)
sorted()
๋ ์ง์ ๋ Comparator๋ก ์คํธ๋ฆผ์ ์ ๋ ฌํ๋๋ฐ, Comparator๋์
int ๊ฐ์ ๋ฐํํ๋ ๋๋ค์์ ์ฌ์ฉํ ์๋ ์๋ค.
Comparator๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด ์คํธ๋ฆผ ์์์ ๊ธฐ๋ณธ ์ ๋ ฌ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค.
ํ์ง๋ง ์คํธ๋ฆผ ์์๊ฐ Comparable์ ๊ตฌํํ ํด๋์ค๊ฐ ์๋๋ฉด ์์ธ๊ฐ ๋ฐ์ํ๋ค.
์ ๋ ฌ์ ์ฌ์ฉ๋๋ ๋ฉ์๋์ ๊ฐ์๊ฐ ๋ง์ง๋ง ๊ธฐ๋ณธ์ ์ธ ๋ฉ์๋๋ comparing()
์ด๋ค.
comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Comparator<U> keyComparator)
์คํธ๋ฆผ ์์๊ฐ Comparable์ ๊ตฌํํ ๊ฒฝ์ฐ, ๋งค๊ฐ๋ณ์ ํ๋์ง๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๊ณ ,
๊ทธ๋ ์ง ์์ผ๋ฉด ์ถ๊ฐ์ ์ธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ ฌ๊ธฐ์ค(Comparator)์ ๋ฐ๋ก ์ง์ ํด์ค์ผ ํ๋ค.
์ ๋ ฌ ์กฐ๊ฑด์ ์ถ๊ฐํ ๋๋ thenComparing()
์ ์ฌ์ฉํ๋ค.
Example
ํ์ ์คํธ๋ฆผ์ ๋ฐ๋ณ, ์ฑ์ ์, ์ด๋ฆ ์์ผ๋ก ์ ๋ ฌํ๋ ์์์ด๋ค.
student.sorted(Comparator.comparing(Student::getBan)
.thenComparing(Student::getTOtalScore)
.thenComparing(Student::getName)
.forEach(System.out.println);
peek
์คํธ๋ฆผ์ ์ด๋ฃจ๋ ๋ชจ๋ ๋ฐ์ดํฐ ๊ฐ๊ฐ์ ๋์์ผ๋ก ํน์ ์ฐ์ฐ์ ์งํํ๋ ํ์๋ฅผ โ๋ฃจํโ์ด๋ผ ํ๋ค.
forEach๋ ๋ฃจํ์ผ๋ก ์ต์ข
์ฐ์ฐ์ด์ง๋ง, ์ค๊ฐ์ฐ์ฐ์๋ ๋ฃจํ ๋ฉ์๋๊ฐ ์๋ค.
๋ฉ์๋
// Stream<T>์ ๋ฉ์๋
Stream<T> peek(Consumer<? super T> action)
Example
class LazyOpStream {
public static void main(String[] args) {
// ์ต์ข
์ฐ์ฐ์ด ์๋ต๋ ์คํธ๋ฆผ์ ํ์ดํ ๋ผ์ธ
// ์๋ฌด ๊ฒ๋ ์ถ๋ ฅ๋์ง ์๋๋ค.
IntStream.of(1, 3, 5)
.peek(d -> System.out.print(d + "\t"));
System.out.println();
// ์ต์ข
์ฐ์ฐ์ด ์กด์ฌํ๋ ํ์ดํ ๋ผ์ธ
IntStream.of(5, 3, 1)
.peek(d -> System.out.print(d + "\t"))
.sum();
System.out.println();
}
}
์คํธ๋ฆผ์ ์ต์ข ์ฐ์ฐ
์ต์ข
์ฐ์ฐ์ ์คํธ๋ฆผ์ ์์๋ฅผ ์๋ชจํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด๋ธ๋ค.
๊ทธ๋์ ์ต์ข
์ฐ์ฐ ํ์๋ ์คํธ์๋ ๋ซํ ๋ ์ด์ ์ฌ์ฉํ ์ ์๋ค.
์ต์ข
์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ ์คํธ๋ฆผ์ ์์์ ํฉ๊ณผ ๊ฐ์ ๋จ์ผ ๊ฐ์ด๊ฑฐ๋,
์คํธ๋ฆผ์ ์์๊ฐ ๋ด๊ธด ๋ฐฐ์ด ๋๋ ์ปฌ๋ ์
์ผ ์ ์๋ค.
forEach
์ง์ ๋ ์์
์ ์คํธ๋ฆผ์ ๋ชจ๋ ์์์ ๋ํด ์ํํ๋ค.
์ฃผ์ํ ์ ์ forEach()
๋ ์คํธ๋ฆผ์ ์์๋ฅผ ์๋ชจํ๋ฉด์ ์์
์ ์ํํ๋ฏ๋ก ๊ฐ์ ์คํธ๋ฆผ์ forEach()
๋ฅผ ๋ ๋ฒ ํธ์ถํ ์ ์๋ค.
๋ฉ์๋
// Stream<T>์ ๋ฉ์๋
void forEach(Consumer<? super T> action)
peek()
๊ณผ ๋ฌ๋ฆฌ ์คํธ๋ฆผ์ ์์๋ฅผ ์๋ชจํ๋ ์ต์ข
์ฐ์ฐ์ด๊ธฐ ๋๋ฌธ์ ๋ฐํํ์ด void์ด๋ค.
reduce
์คํธ๋ฆผ ์์๋ฅผ ์ค์ฌ๋๊ฐ๋ฉด์ ์ฐ์ฐ์ ์ํํ๊ณ ์ต์ข
๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
์ฒ์ ๋ ์์๋ฅผ ๊ฐ์ง๊ณ ์ฐ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ๊ทธ ๋ค์ ์์์ ์ฐ์ฐํ๋ค.
์ด ๊ณผ์ ์์ ์คํธ๋ฆผ์ ์์๋ฅผ ํ๋์ฉ ์๋ชจํ๊ฒ ๋๋ฉฐ, ์คํธ๋ฆผ์ ๋ชจ๋ ์์๋ฅผ ์๋ชจํ๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
์คํธ๋ฆผ์ ์์๊ฐ ํ๋๋ ์๋ ๊ฒฝ์ฐ, ์ด๊ธฐ๊ฐ์ด ๋ฐํ๋๋ฏ๋ก ๋ฐํํ์
์ด Optional<T>
๊ฐ ์๋๋ผ T
์ด๋ค.
๋ฉ์๋
T reduce(T identity, BinaryOperator<T> accumulator) // Stream<T>์ ์กด์ฌ
reduce๋ ์ ๋ฌํ๋ ๋๋ค์์ ์ํด ์ฐ์ฐ์ ๋ด์ฉ์ด ๊ฒฐ์ ๋๋ค.
BinaryOperator<T>
์ ์ถ์ ๋ฉ์๋
T apply(T t1, T t2)
reduce ํธ์ถ ์ ๋ฉ์๋ apply์ ๋ํ ๋๋ค์์ ์ธ์๋ก ์ ๋ฌํด์ผ ํ๋ค.
class ReduceStream {
public static void main(String[] args) {
List<String> ls = Arrays.asList("Box", "Simple", "Complex", "Robot");
BinaryOperator<String> lc =
(s1, s2) -> {
if(s1.length() > s2.length())
return s1;
else
return s2;
};
String str = ls.stream()
.reduce("", lc); // ์คํธ๋ฆผ์ด ๋น ๊ฒฝ์ฐ ๋น ๋ฌธ์์ด ๋ฐํ
System.out.println(str); // Complex
}
}
reduce ๋ฉ์๋๋ ์คํธ๋ฆผ์ด ๋น ๊ฒฝ์ฐ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋ ๊ฐ์ ๋ฐํํ๋ค.
allMatch, anyMatch, noneMatch
์คํธ๋ฆผ์ ์์์ ๋ํด ์ง์ ๋ ์กฐ๊ฑด์ ๋ชจ๋ ์์๊ฐ ์ผ์นํ๋ ์ง, ์ผ๋ถ๊ฐ ์ผ์นํ๋์ง,
์๋๋ฉด ์ด๋ค ์์๋ ์ผ์นํ์ง ์๋์ง ํ์ธํ๋๋ฐ ์ฌ์ฉํ ์ ์๋ค.
๋ฉ์๋
boolean allMatch(Predicate<? super Y> predicate)
boolean anyMatch(Predicate<? super Y> predicate)
boolean noneMatch(Predicate<? super Y> predicate)
- allMatch : ์คํธ๋ฆผ์ ๋ฐ์ดํฐ๊ฐ ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ๋๊ฐ?
- anyMatch : ์คํธ๋ฆผ์ ๋ฐ์ดํฐ๊ฐ ์กฐ๊ฑด์ ํ๋๋ผ๋ ๋ง์กฑํ๋๊ฐ?
- noneMatch : ์คํธ๋ฆผ์ ๋ฐ์ดํฐ๊ฐ ์กฐ๊ฑด์ ํ๋๋ ๋ง์กฑํ์ง ์๋๊ฐ?
findAny, findFirst
filter()
์ ํจ๊ป ์ฐ์ฌ์ ์กฐ๊ฑด์ ๋ง๋ ์คํธ๋ฆผ์ ์์๊ฐ ์๋์ง ํ์ธํ๋๋ฐ ์ฌ์ฉ๋๋ค.
๋์ ๋ฐํ ํ์ ์Optionsnal<T>
์ด๋ฉฐ, ์คํธ๋ฆผ์ ์์๊ฐ ์์ ๋ ๋น Optional ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Example
Optional<Student> result = student.filer(s -> s.getTotalScore() <= 100).findFirst();
collect
ํ์ดํ๋ผ์ธ์ ํตํด์ ๊ฐ๊ณต๋๊ณ ๊ฑธ๋ฌ์ง ๋ฐ์ดํฐ๋ฅผ ์ต์ข ์ฐ์ฐ ๊ณผ์ ์์ ๋ณ๋๋ก ์ ์ฅ์ด ํ์ํ ๋ ์ฌ์ฉํ๋ค.
๋ฉ์๋
// Stream<T>์ ๋ฉ์๋
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner)
Example
class CollectStringStream {
public static void main(String[] args) {
String[] words = {"Hello", "Box", "Robot", "Toy"};
Stream<String> ss = Arrays.stream(words);
List<String> ls = ss.filter(s -> s.length() < 5)
.collect(
() -> new ArrayList<>(),
(c, s) -> c.add(s),
(lst1, lst2) -> lst1.addAll(lst2));
System.out.println(ls); // [Box, Toy]
}
}
์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ธ ๋๋ค์์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์ฅ์๋ฅผ ์์ฑํ๋ค.
๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ธ ๋๋ค์์์์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์(c)๋
collect์ ์ฒซ๋ฒ์งธ ์ธ์๋ฅผ ํตํด์ ์์ฑ๋ ์ปฌ๋ ์
์ธ์คํด์ค์ด๋ฉฐ,
๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์(s)๋ ์คํธ๋ฆผ์ ์ด๋ฃจ๋ ๋ฐ์ดํฐ ์ด๋ค.
์ธ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ธ ๋๋ค์์ ๋ณ๋ ฌ ์คํธ๋ฆผ์ด ์๋ ์์ฐจ ์คํธ๋ฆผ์ผ ๊ฒฝ์ฐ ์ฌ์ฉ๋์ง ์๋๋ค.
collect()
์คํธ๋ฆผ์ ์์๋ฅผ ์์งํ๋ ์ต์ข
์ฐ์ฐ์ผ๋ก reduce()
์ ์ ์ฌํ๋ค.
collect()๊ฐ ์คํธ๋ฆผ์ ์์๋ฅผ ์์งํ๋ ค๋ฉด, ์ด๋ป๊ฒ ์์งํ ๊ฒ์ธ๊ฐ์ ๋ํ ๋ฐฉ๋ฒ์ด ์ ์๋์ด
์์ด์ผ ํ๋๋ฐ, ์ด ๋ฐฉ๋ฒ์ ์ ์ํ ๊ฒ์ด ์ปฌ๋ ํฐ์ด๋ค.
์ปฌ๋ ํฐ
์ปฌ๋ ํฐ๋ Collector
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฒ์ผ๋ก, ์ง์ ๊ตฌํํ ์๋ ์๊ณ ๋ฏธ๋ฆฌ ์์ฑ๋ ๊ฒ์ ์ฌ์ฉํ ์๋ ์๋ค.
๋ค์ํ static ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
- collect() : ์คํธ๋ฆผ์ ์ต์ข ์ฐ์ฐ, ๋งค๊ฐ๋ณ์๋ก ์ปฌ๋ ํฐ๋ฅผ ํ์๋ก ํ๋ค.
- Collector : ์ธํฐํ์ด์ค. ์ปฌ๋ ํฐ๋ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผํ๋ค.
- Collectors : ํด๋์ค. static ๋ฉ์๋๋ก ๋ฏธ๋ฆฌ ์์ฑ๋ ์ปฌ๋ ํฐ๋ฅผ ์ ๊ณตํ๋ค.
Collector๋ ์ธํฐํ์ด์ค์ด๊ธฐ ๋๋ฌธ์ ์ง์ ๊ตฌํํด์ ์ปฌ๋ ํฐ๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
collect()
collect()
๋ ๋งค๊ฐ๋ณ์ ํ์
์ด Collector์ธ๋ฐ, ๋งค๊ฐ๋ณ์๊ฐ Collector๋ฅผ ๊ตฌํํ ํด๋์ค์ ๊ฐ์ฒด์ฌ์ผ ํ๋ค.
collect()
๋ ์ด ๊ฐ์ฒด์ ๊ตฌํ๋ ๋ฐฉ๋ฒ๋๋ก ์คํธ๋ฆผ์ ์์๋ฅผ ์์งํ๋ค.
sort()ํ ๋ Comparator๊ฐ ํ์ํ ๊ฒ์ฒ๋ผ colllect()ํ ๋๋ Collector๊ฐ ํ์ํ๋ค.
Object collect(Collector collector)
์คํธ๋ฆผ์ ์ปฌ๋ ์ ๊ณผ ๋ฐฐ์ด๋ก ๋ฐํ
toList()
,toSet()
,toMap()
,toCollection()
,toArray()
์คํธ๋ฆผ์ ๋ชจ๋ ์์๋ฅผ ์ปฌ๋ ์
์ ์์งํ๋ ค๋ฉด, Collectors ํด๋์ค์ toList()
์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
ํน์ ์ปฌ๋ ์
์ ์ง์ ํ๋ ค๋ฉด toCollection()
์ ํด๋นํ๋ ์ปฌ๋ ์
์
์์ฑ์ ์ฐธ์กฐ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
ArrayList<String> list = names.stream().collect(Collectors.toCollection(toCollection(ArrayList::new));
Map์ ํค์ ๊ฐ์ ์์ผ๋ก ์ ์ฅํด์ผํ๋ ๊ฐ์ฒด์ ์ด๋ค ํ๋๋ฅผ ํค๋ก ์ฌ์ฉํ ์ง์ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ง๋ฅผ ์ง์ ํด์ค์ผ ํ๋ค.
์๋ ์์ ๋ ์คํธ๋ฆผ์์ ์ฌ๋์ ์ฃผ๋ฏผ๋ฒํธ๋ฅผ ํค๋ก ํ๊ณ , ๊ฐ์ผ๋ก Person ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ์ ์ฅํ๋ค.
Map<String, Person> map = personStream.collect(Collectors.toMap(p->p.getRegId(), p->p));
์ฐธ๊ณ ์๋ฃ
- ์๋ฐ์ ์ ์
- ์ค์ฑ์ฐ์ ์ดํ ์๋ฐ ํ๋ก๊ทธ๋๋ฐ
์์ฃผ ์ฌ์ฉํ๋ ์คํธ๋ฆผ์ ์ ๋ฆฌํ๋๊น ๊ฐ ๋ฉ์๋์ ์ฌ์ฉ ๋ชฉ์ ์ด ๋ช
ํํด์ก๋ค ๐
๋ Collector์ Collectors๋ ๋ญ๊ฐ ๋ค๋ฅธ์ง ๊ถ๊ธํ๋๋ฐ ์ ๋ฆฌ๋์๋ค.