JAVA Stream API ํน์ง
Table of contents
- Stream ์ด๋!
- ์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
- ์คํธ๋ฆผ์ ์ผํ์ฉ์ด๋ค.
- ์คํธ๋ฆผ์ ์์ ์ ๋ด๋ถ ๋ฐ๋ณต์ผ๋ก ์ฒ๋ฆฌํ๋ค.
- ์ง์ฐ ์ฐ์ฐ
- ๋ณ๋ ฌ ์คํธ๋ฆผ
Stream API ํต์ฌ!
Java8์ ์ถ๊ฐ๋ Stream API๋ ๋ค๋์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ ์์ฌ์ด ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ง๋ค์ด์ก๋ค.
Stream API๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ Collection์ ๊ฐ๋ ์ด ์๋๋ผ ์ด๋ค ์ํ์ค ์์๋ค์ ์์ฐจ ๋ฐ ๋ณ๋ ฌ ์ง๊ณ ์์ ์ ์ง์ํด์ฃผ๋ API์ด๋ค.
ํน์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
- ์คํธ๋ฆผ์ด ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ์์ค๋ ๋ณ๊ฒฝ๋์ง ์๋๋ค.(์๋ณธ ๋ฐ์ดํฐ๋ฅผ ํผ์ํ์ง ์๋๋ค.)
- ์คํธ๋ฆผ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ๋ ์ค์ง ํ ๋ฒ๋ง ์ฒ๋ฆฌ๋๋ค.
- ์ต์ข ์ฐ์ฐ์ด ์ํ๋๊ธฐ ์ ๊น์ง๋ ์ค๊ฐ ์ฐ์ฐ์ด ์ํ๋์ง ์๋๋ค.
- ์์ฌ์ด ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๋ค.
Stream ์ด๋!
๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋, ์ปฌ๋ ์ ์ด๋ ๋ฐฐ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ
์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ์ํด for๋ฌธ๊ณผ Iterator๋ฅผ ์ด์ฉํด์ ์ฝ๋๋ฅผ ์์ฑํด์๋ค.
์ด๋ฐ ๋ฐฉ์์ผ๋ก ์์ฑ๋ ์ฝ๋๋ ๋๋ฌด ๊ธธ๊ณ ์์๋ณด๊ธฐ ์ด๋ ต๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ฌ์ฉ์ฑ๋ ๋จ์ด์ง๋ค.
๋ฐฐ์ด์ ์ ๋ ฌํ ๋๋, Arrays.sort()
List๋ฅผ ์ ๋ ฌํ ๋๋, Collections.sort()
๋ํ, ๋ฐ์ดํฐ ์์ค๋ง๋ค ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋ค๋ค์ผ ํ๋ค๋ ์ ๋ ์๋ค.
// String ๋ฐฐ์ด์ด ์์ ๋, ์ ๋ ฌํ ๋ค ์์๋ฅผ ์ถ๋ ฅํด์ผ ํ ๋
String [] strArr = {"aaa","ddd","ccc"}
// 1. ์ผ๋ฐ์ ์ธ ๋ฐฉ์
Arrays.sort(strArr);
for(String str : strArr){
System.out.println(str)
}
// 2. ์คํธ๋ฆผ ๋ฐฉ์
Arrays.stream(strArr).sorted().forEach(System.out::println)
์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ถ์ํํ๊ณ , ์ถ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋๋ฐ ์์ฃผ ์ฌ์ฉ๋๋ ๋ฉ์๋๋ค์ ์ ์ํด๋์๋ค.
๋ฐ์ดํฐ ์์ค๊ฐ ๋ฌด์์ด๋ ๊ฐ์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค์ด๋๊ธฐ๋ง ํ๋ฉด, ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ค๋ฃฐ ์ ์์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ด ๋์์ง๊ณ , ์ฝ๋ ๊ฐ๋ ์ฑ๋ ๋์์ง๋ค.
๋ํ ์คํธ๋ฆผ์์ ์ ์ํ ๋ฉ์๋ ๋๋ก ๋ถํ์ํ ์ธ์คํด์ค ์์ฑ ๊ณผ์ ์ ์๋ตํ ์ ์์ด, ๋ฉ๋ชจ๋ฆฌ ๊ด์ ์์ ํจ์จ์ ์ธ ๋ฌธ๋ฒ์ด๋ค.
์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
์คํธ๋ฆผ์ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
๋จ์ ์ธ ์๋ก,
Arrays.stream(strArr).sorted().forEach(System.out::println)
์ ๋ฉ์๋๋ฅผ ์คํํ๋ค๊ณ ํด์, strArr ๋ฐฐ์ด์ ๋ณํ๊ฐ ์๊ธฐ์ง ์๋ ๊ฒ๊ณผ ๊ฐ๋ค.
List<String> collect = Arrays.stream(strArr).sorted().collect(Collectors.toList());
์คํธ๋ฆผ์ผ๋ก ๋ณ๊ฒฝ์ ์ํจ ๋ฐ์ดํฐ๊ฐ ํ์ํ๋ค๋ฉด, ์์ ๊ฐ์ด .collect(Collectors.toList()) ์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ฐํํ ์ ์๋ค.
์คํธ๋ฆผ์ ์ผํ์ฉ์ด๋ค.
public class Test {
public static void main(String[] args) {
String[] strArr = {"aaa", "ddd", "ccc"};
Stream<String> stream = Arrays.stream(strArr);
stream.forEach(System.out::println);
//2๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
stream.forEach(System.out::println);
}
}
์์ ๊ฐ์ด ์ฒซ๋ฒ์งธ forEach() ๋ ๋์์ ํ์ง๋ง,
๋๋ฒ์งธ๋ถํฐ๋ ์ด๋ฏธ ์ฌ์ฉํ๋ stream์ ์ฌ์ฉํ ์ ์๋ค.
์คํธ๋ฆผ์ ์์ ์ ๋ด๋ถ ๋ฐ๋ณต์ผ๋ก ์ฒ๋ฆฌํ๋ค.
๋ฐ๋ณต๋ฌธ์ ๋ฉ์๋ ๋ด๋ถ์ ์จ๊ธธ ์ ์์ด ๊ฐ๊ฒฐํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ์ด๋ค.
EX) stream().forEach()
void forEach(Consumer<? super T> action){
Objects.requireNonNull(action);
for(T t : src){
action.accpet(T)
}
}
์ํํ ์์ ์ ํจ์ํ ์ธํฐํ์ด์ค์ ํํ๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ๋์์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์ฐ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
์ง์ฐ ์ฐ์ฐ
public class Test {
public static void main(String[] args) {
Integer[] arr = {1, 2, 3};
Arrays.stream(arr)
.peek((i)->System.out.println(i+"์คํ"))
.forEach((i) -> System.out.println(i+"์๋ฃ"));
}
}
์ ์ฝ๋์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ์ด๋ป๊ฒ ๋ ๊น?
1์คํ
2์คํ
3์คํ
1์๋ฃ
2์๋ฃ
3์๋ฃ
์ค๊ฐ ์ฐ์ฐ๋ง๋ค ๋ชจ๋ ์์๋ฅผ ์ํํด์ ์ฐ์ฐ์ ๋ง์นํ ๋ค์ ์ฐ์ฐ์ ๋๊ธฐ๋ ๋ฐฉ์์ธ
์์ ๊ฐ์ด ์คํ๋ ๊ฒ ๊ฐ์ง๋ง
1์คํ
1์๋ฃ
2์คํ
2์๋ฃ
3์คํ
3์๋ฃ
์ ๊ฒฐ๊ณผ ์ฒ๋ผ, ๊ฐ ์์๋ฅผ ์ต์ข ์ฐ์ฐ๊น์ง ์งํํ๋ค.
์ด๋ค ๊ฒ์ด ํจ์จ์ ์ผ์ง ์๊ฐํด๋ณด์
for(Integer i : arr){
print(i)
}
for(Intger i : arr){
System.out.println(i+"์๋ฃ")
}
//์ถ๋ ฅ ๊ฒฐ๊ณผ
1์คํ
2์คํ
3์คํ
1์๋ฃ
2์๋ฃ
3์๋ฃ
for(Integer i : arr){
print(i)
System.out.println(i+"์๋ฃ")
}
//์ถ๋ ฅ ๊ฒฐ๊ณผ
1์คํ
1์๋ฃ
2์คํ
2์๋ฃ
3์คํ
3์๋ฃ
for๋ฌธ์ผ๋ก ํ์ด์ ์๊ฐํด๋ณด๋ฉด, ์ฒซ๋ฒ์งธ ์ผ์ด์ค์ ๊ฒฝ์ฐ for๋ฌธ์ 2๋ฒ ๋์ง๋ง, ๋๋ฒ์งธ ์ผ์ด์ค์ ๊ฒฝ์ฐ for๋ฌธ์ 1๋ฒ๋ง ๋์๋ ๋๋ค.
public class Test {
public static void main(String[] args) {
Integer[] arr = {3, 2, 1};
Arrays.stream(arr)
.peek((i)->System.out.println(i+"์คํ"))
.sorted()
.forEach((i) -> System.out.println(i+"์๋ฃ"));
}
}
//์ถ๋ ฅ๊ฒฐ๊ณผ
3์คํ
2์คํ
1์คํ
//์ฌ๊ธฐ์ sorted์์
์ด ์งํ๋์ด์ผ ํ๋ฏ๋ก for๋ฌธ์ด ๋ถ๋ฆฌ๋จ
1์๋ฃ
2์๋ฃ
3์๋ฃ
๐ statefulํ ์ค๊ฐ ์ฐ์ฐ
- stateful (์ด์ ์ํ๋ฅผ ์ฐธ์กฐํด์ผํ๋ ์ฐ์ฐ) : distinct, sortedโฆ
- stateless (์ด์ ์ํ๋ฅผ ์ฐธ์กฐํ์ง ์๋ ์ฐ์ฐ) : filter, map, limit, skipโฆ
sorted์ ๊ฐ์ statefulํ ์ฐ์ฐ์ ๊ฒฝ์ฐ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ฃผ์ด์ ธ์ผ ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง๋ง, filter์ ๊ฐ์ statelessํ ์ฐ์ฐ์ ๊ฒฝ์ฐ, ํ ์์๋ง๋ค ๊ฒฐ๊ณผ๋ฅผ ๋๊ธธ ์ ์๋ค.
์์ ๊ฐ์ ์๋ฆฌ๋ก, ์ค๊ฐ ์ฐ์ฐ์ ํํ์ ๋ฐ๋ผ ์ฐ์ฐ ์์๊ฐ ์ ํด์ง๊ณ , forEach()์ ๊ฐ์ ์ต์ข ์ฐ์ฐ์ ๋ง๋๊ฒ ๋๋ฉด ์ค๊ฐ ์ฐ์ฐ์ด ์คํ๋๋ค.
Arrays.stream(arr)
.peek((i)->System.out.println(i+"์คํ"))
.sorted();
์์ ๊ฐ์ ์ฝ๋๋ ์ต์ข ์ฐ์ฐ ๋ฉ์๋๊ฐ ์์ผ๋ฏ๋ก ์คํ๋์ง ์๋๋ค.
๋ณ๋ ฌ ์คํธ๋ฆผ
์คํธ๋ฆผ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ฉด ๋ณ๋ ฌ์ฒ๋ฆฌ๊ฐ ์ฝ๋ค.
์คํธ๋ฆผ์ parallel() ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ฉด ๋ณ๋ ฌ๋ก ์ฐ์ฐ์ ์ํํ๋ค.
// ์ผ๋ฐ์ ์ธ ์ฒ๋ฆฌ (squential ์๋ต ๊ฐ๋ฅ)
Arrays.stream(arr).sequential().sorted()
.toArray();
// ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋ช
์์ ์ง์
Arrays.stream(arr).parallel().sorted()
.toArray();
๋ณ๋ ฌ์ฒ๋ฆฌ์ ๊ฒฝ์ฐ ์์ ์ ๋๋๊ณ ๋ค์ ํฉ์น๋ ์๊ฐ์ด ํ์ํ๋ฏ๋ก ํญ์ ๋ ๋น ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ฒ ํด์ฃผ๋ ๊ฒ์ ์๋๋ค.
์คํธ๋ฆผ ์์ค์ธ Collections์ด splitํ๊ธฐ ์ฌ์ด ์๋ฃ๊ตฌ์กฐ์ด์ด์ผ ํ๋ฉฐ, ์ฐ์ฐ์ด stateful ํ์ง ์์์ผ ํ๋ค.
๐ LinkedList vs ArrayList
LikedList๋ next()๋ฅผ ํตํด ๊ฐ์ ์ผ์ผ์ด ์ฐธ์กฐํด์ผํ๋๋ฐ, ArryList๋ index๋ฅผ ํตํด List ๊ฐ์ ์ ๊ทผํ ์ ์์ด ์์ ์ split()ํ๋๋ฐ ๋น์ฉ์ด ์ ๊ฒ ๋ ๋ค.
LikedList ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ค๋ฃฐ๋, for-loop ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋น ๋ฅด๋ค.
๋ฐ๋ผ์, ํ ์คํธ ํด๋ณด๊ณ ๊ฒฐ์ ํ๋ ๊ฒ์ด ์ข๋ค.
์ฐธ๊ณ ํ ๋ธ๋ก๊ทธ