๐ฐJava Stream
Java 8
ํน์ง
- ์ฐ์๋ ์ ๋ณด๋ฅผ ์ฒ๋ฆฌํ๋๋ฐ ์ฌ์ฉํ๋ค.
- Sequence of elements supporting sequential and parallel aggregate operations
-
๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ์ ์ฅ์(์ปฌ๋ ์ )์ด ์๋๋ค.
Functional in nature
: stream์ ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค.
List<String> names = new ArrayList<>();
names.add("test");
names.stream().map(String::toUpperCase).forEach(System.out::println);
names.forEach(System.out::println);
> TEST
> test
- ํ๋์ ๋ฐ์ดํฐ๋ฅผ ์ค์ง ํ๋ฒ๋ง ์ฒ๋ฆฌํ๋ค.
- ๋คํธ์ํฌ ๋ฑ ๋ฌด์ ํ stream์ด ์์ ์๋ ์๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ Short Circuit ๋ฉ์๋๋ก ์ ํํ ์ ์๋ค.
- ์ค๊ฐ ์ฐ์ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก lazyํ๋ค.
List<String> names = new ArrayList<>();
names.add("test");
names.stream().map(s -> {
System.out.println(s); // ์ข
๋จ ์ฐ์ฐ ์ ๊น์ง๋ ์คํ๋์ง ์๋๋ค.
return s.toUpperCase();
});
names.forEach(System.out::println);
> test
parallelStream
์ ์ด์ฉํ์ฌ ์์ฝ๊ฒ ๋ณ๋ ฌ ์ฒ๋ฆฌํ ์ ์๋ค.
List<String> names = new ArrayList<>();
names.add("test1");
names.add("test2");
List<String> collect = names.parallelStream().map(s -> s.toUpperCase()).collect(Collectors.toList());
collect.forEach(System.out::println);
์คํธ๋ฆผ ํ์ดํ๋ผ์ธ
์ค๊ฐ ์ฐ์ฐ
- stream์ ๋ฐํํ๋ค.
- stateless์ stateful ๋ฐฉ์์ผ๋ก ๋๋ ์ ์๋ค. ๋๋ถ๋ถ stateless์ด์ง๋ง distinct๋ sorted ๊ฐ์ ๊ฒฝ์ฐ stateful์ด๋ค.
filter
,map
,limit
,skip
,sorted
, โฆ
์ข ๋จ ์ฐ์ฐ
- stream์ ๋ฐํํ์ง ์๋๋ค.
collect
,allMatch
,count
,forEach
,min
,max
, โฆ
์คํธ๋ฆผ API
๊ฑธ๋ฌ๋ด๊ธฐ
filter(predicate)
- ํน์ ์กฐ๊ฑด(predicate)๋ฅผ ๋ง์กฑํ๋ element๋ง ์๋ก์ด
stream
์ผ๋ก ๋ฐํํ๋ค. - filter(Predicate.not(OnlineClass::isClosed)) -> !์ ๊ฐ์ ์ฐ์ฐ์๋ ์ฌ์ฉํ ์ ์๋ค.
๋ณ๊ฒฝํ๊ธฐ
map(function)
,flatMap(function)
- ๊ฐ๊ฐ์ ์์์์ ํน์ ์์๋ง ๊บผ๋ด๊ฑฐ๋ ๋ณ๊ฒฝํ์ฌ ์๋ก์ด
stream
์ผ๋ก ๋ฐํํ๋ค. - (ex) List<Stream
> -> String์ ์คํธ๋ฆผ์ผ๋ก ๋ณํ
์์ฑํ๊ธฐ
generate(Supplier)
๋๋iterate(T seed, UnaryOperator)
- seed๋ก ๋ถํฐ UnaryOperator๋ฅผ ๋ฌด์ ํ์ผ๋ก ๋ฐ๋ณตํ๋
stream
์ ๋ฐํํ๋ค. - Random integer ๋ฌด์ ํ ์คํธ๋ฆผ ๋ฑ์ด ๊ฐ๋ฅํ๋ค.
์ ํํ๊ธฐ
limit(long)
,skip(long)
- (ex) ์์์ 3๊ฐ๋ฅผ ๋บ ๋๋จธ์ง
stream
์ ๋ฐํํ๋ค.
Stream์ ์๋ ๋ฐ์ดํฐ๊ฐ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ํ์ธ
anyMatch()
,allMatch()
,nonMatch()
stream
์ element ๋ค์ ๋๋ฉด์ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ํ์ธํ๋ค.- (ex) ์ ๋ชฉ ์ค test๊ฐ ๋ค์ด๊ฐ๋์ง
๊ฐ์ ์ธ๊ธฐ
count()
Stream์ ๋ฐ์ดํฐ ํ๋๋ก ๋ญ์น๊ธฐ
reduce(identity, BiFunction)
,collect()
,sum()
,max()
ํตํฉ ์์
// ๋ฐ์ดํฐ ์ค๋น
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(2, "spring data jpa", true));
springClasses.add(new OnlineClass(3, "spring mvc", false));
springClasses.add(new OnlineClass(4, "spring core", false));
springClasses.add(new OnlineClass(5, "rest api development", false));
List<OnlineClass> javaClasses = new ArrayList<>();
javaClasses.add(new OnlineClass(6, "The Java, Test", true));
javaClasses.add(new OnlineClass(7, "The Java, Code mainpulation", true));
javaClasses.add(new OnlineClass(8, "The Java 8 to 11", false));
List<List<OnlineClass>> events = new ArrayList<>();
events.add(springClasses);
events.add(javaClasses);
// spring์ผ๋ก ์์ํ๋ ์์
springClasses.stream()
.filter(oc -> oc.getTitle().startsWith("spring")
.forEach(System.out::println);
// closed๋์ง ์๋ ์์
springClasses.stream()
.filter(Predicate.not(OnlineClass::isClosed))
.forEach(System.out::println);
// ์์
์ด๋ฆ๋ง ๋ชจ์์ stream๋ง๋ค๊ธฐ
Stream<String> springTitleStream = springClasses.stream()
.map(OnlineClass::getTitle);
// ๋ ์์
๋ชฉ๋ก์ ๋ค์ด์๋ ๋ชจ๋ ์์
์์ด๋ ์ถ๋ ฅ
events.stream()
.flatMap(Collection::stream) // 2์ฐจ์ ๋ฆฌ์คํธ๋ฅผ 1์ฐจ์์ผ๋ก ํํํ
.forEach(oc -> System.out.println(oc.getId());
// 10๋ถํฐ 1์ฉ ์ฆ๊ฐํ๋ ๋ฌด์ ํ ์คํธ๋ฆผ ์ค์์ ์์ 10๊ฐ ๋นผ๊ณ ์ต๋ 10๊ฐ๊น์ง๋ง
Stream.iterate(10, i -> i + 1)
.skip(10)
.limit(10)
.forEach(System.out::println);
// ์๋ฐ ์์
์ค์ Test๊ฐ ๋ค์ด์๋ ์์
์ด "์๋์ง" ํ์ธ
boolean test = jaaClasses.stream()
.anyMatch(oc -> oc.getTitle().contains("Test"));
// ์คํ๋ง ์์
์ค์ ์ ๋ชฉ์ด spring์ด ๋ค์ด๊ฐ ์ ๋ชฉ๋ง ๋ชจ์์ List๋ก ๋ง๋ค๊ธฐ
List<String> spring = springClasses.stream()
.filter(oc -> oc.getTitle().contains("spring")
.map(OnlineClass::getTitle)
.collect(Collector.toList());
[1] ๋ฐฑ๊ธฐ์ , ๋ ์๋ฐ Java 8, Optional