1.1 ์๋ฐ์ ์งํ
๐ ์๋ฐ์ ํน์ฑ
- ์ค๋ ๋์ ๋ฝ์ ์ด์ฉํ ๋์์ฑ ์ง์
- ์ฝ๋๋ฅผ JVM ๋ฐ์ดํธ ์ฝ๋๋ก ์ปดํ์ผ
๐ ์๋ฐ์ ๋ฐ์
์๋ฐ 8 ์ด์ ์ ๋๋ถ๋ถ์ ์๋ฐ ํ๋ก๊ทธ๋จ์ ์ฝ์ด ์ค ํ๋๋ง์ ์ฌ์ฉํ๋ค. ์ฆ, ๋๋จธ์ง ์ฝ์ด๋ ์ ํด idle ์ํ๋ก ๋๊ฑฐ๋, ์ด์์ฒด์ ๋ ๋ฐ์ด๋ฌ์ค ๊ฒ์ฌ ํ๋ก๊ทธ๋จ๊ณผ ํ๋ก์ธ์ค ํ์๋ฅผ ๋๋์ด์ ์ฌ์ฉํ๋ค.
๋๋จธ์ง ์ฝ์ด๋ฅผ ํ์ฉํ๊ธฐ ์ํด์๋ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ค. ํ์ง๋ง ์ค๋ ๋๋ ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์ฐ๋ฏ๋ก ๋ณ๋ ฌ ์คํ ํ๊ฒฝ์ ์ฝ๊ฒ ๊ด๋ฆฌํ๊ณ ์๋ฌ๊ฐ ๋ ๋ฐ์ํ๋ ๋ฐฉํฅ์ผ๋ก ์งํํ๋ ค ๋ ธ๋ ฅํ๋ค.
- ์๋ฐ 1.0 : ์ค๋ ๋์ ๋ฝ, ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ ์ง์
- ์๋ฐ 5 : ์ค๋ ๋ ํ, ๋ณ๋ ฌ ์คํ ์ปฌ๋ ์
- ์๋ฐ 7 : ํฌํฌ/์กฐ์ธ ํ๋ ์์ํฌ
- ์๋ฐ 8 : ๋ณ๋ ฌ ์คํ์ ์๋กญ๊ณ ๋จ์ํ ๋ฐฉ์์ผ๋ก ์ ๊ทผํ ์ ์๋ ๋ฐฉ๋ฒ ์ ๊ณต
- ์๋ฐ 9 : ๋ฆฌ์กํฐ๋ธ ํ๋ก๊ทธ๋๋ฐ(๋ณ๋ ฌ ์คํ ๊ธฐ๋ฒ), RxJava
1.2 JAVA 8์ ์๋ก์ด ๊ธฐ์
- ์คํธ๋ฆผ API
- ๋ฉ์๋์ ์ฝ๋๋ฅผ ์ ๋ฌํ๋ ๊ธฐ๋ฒ
- ์ธํฐํ์ด์ค์ ๋ํดํธ ๋ฉ์๋
๐ Stream API
์คํธ๋ฆผ์ด๋, ํ ๋ฒ์ ํ ๊ฐ์ฉ ๋ง๋ค์ด์ง๋ ์ฐ์์ ์ธ ๋ฐ์ดํฐ ํญ๋ชฉ๋ค์ ๋ชจ์์ด๋ค. ํ๋ก๊ทธ๋จ์ ์ถ๋ ฅ ์คํธ๋ฆผ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ์ ๋ ฅ ์คํธ๋ฆผ์ด ๋ ์ ์๋ค.
์๋ฐ 8์๋ java.util.stream ํจํค์ง์ ์คํธ๋ฆผ API๊ฐ ์ถ๊ฐ๋์๋ค. Stream<T>๋ T ํ์์ผ๋ก ๊ตฌ์ฑ๋ ์ผ๋ จ์ ํญ๋ชฉ์ ์๋ฏธํ๋ค. ์คํธ๋ฆผ API์ ํต์ฌ์ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ จ์ ์คํธ๋ฆผ์ผ๋ก ๋ง๋ค์ด ์ฒ๋ฆฌํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ง์ ์ธ์ด์์ ํํ์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ฒ๋ผ ๋ณ๋ ฌ ์ฐ์ฐ์ ์ง์ํ๋ค. ์คํธ๋ฆผ์ ์ด์ฉํ๋ฉด synchronized(์๋ฌ๋ฅผ ์์ฃผ ์ผ์ผํค๋ฉฐ ๋ฉํฐ์ฝ์ด CPU๋ฅผ ์ด์ฉํ๋ ๊ฒ๋ณด๋ค ๋น์ฉ์ด ํจ์ฌ ๋น์ผ ํค์๋)๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
๋ฉํฐ์ฝ์ด CPU์ ๊ฐ ์ฝ์ด๋ ๋ณ๋์ ์บ์๋ฅผ ํฌํจํ๊ณ ์๋ค. ๋ฝ์ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ์บ์๊ฐ ๋๊ธฐํ๋์ด์ผ ํ๋ฏ๋ก ์๋๊ฐ ๋๋ฆฐ ์บ์ ์ผ๊ด์ฑ ํ๋กํ ์ฝ ์ธํฐ์ฝ์ด ํต์ ์ด ์ด๋ฃจ์ด์ง๋ค.
์คํธ๋ฆผ API ๋๋ถ์
- ์ฝ๋๋ฅผ ์ ๋ฌํ๋ ๊ฐ๊ฒฐ ๊ธฐ๋ฒ(๋ฉ์๋ ์ฐธ์กฐ์ ๋๋ค)
- ์ธํฐํ์ด์ค์ ๋ํดํธ ๋ฉ์๋
๊ฐ ์กด์ฌํ ์ ์๊ฒ ๋์๋ค.
๐ ๋์ ํ๋ผ๋ฏธํฐํ๋ก ๋ฉ์๋์ ์ฝ๋ ์ ๋ฌํ๊ธฐ
์ฝ๋ ์ผ๋ถ๋ฅผ API๋ก ์ ๋ฌํ๋ ๊ธฐ๋ฅ์ด๋ค. ์๋ฅผ ๋ค์ด, ๊ธฐ์กด์๋ sort ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋ Comparator ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ sort์ ๋๊ฒจ์ฃผ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์๋ค. ๊ทธ๋ฌ๋ ์๋ฐ 8์์๋ ๋ฉ์๋๋ฅผ ๋ค๋ฅธ ๋ฉ์๋์ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ๊ธฐ๋ฅ(๋์ ํ๋ผ๋ฏธํฐํ)์ ์ ๊ณตํ๋ค. inventory.sort(comparing(Apple::getWeight));
๐ ๋ณ๋ ฌ์ฑ๊ณผ ๊ณต์ ๊ฐ๋ณ ๋ฐ์ดํฐ
์คํธ๋ฆผ ๋ฉ์๋๋ก ์ ๋ฌํ๋ ์ฝ๋๋ ๋ค๋ฅธ ์ฝ๋์ ๋์์ ์คํํ๋๋ผ๋ ์์ ํ๊ฒ ์คํ๋ ์ ์์ด์ผ ํ๋ค. (๋ณ๋ ฌ์ฑ)
์ด๋ฅผ ์ํด์๋ ๊ณต์ ๋ ๊ฐ๋ณ ๋ฐ์ดํฐ์ ์ ๊ทผํ์ง ์์์ผ ํ๋ค. ๊ธฐ์กด์๋ synchronized๋ฅผ ์ด์ฉํด์ ๋ณดํธํ๋ ๊ท์น์ ๋ง๋ค ๊ฒ์ด์ง๋ง, ์๋ฐ 8 ์คํธ๋ฆผ์ ์ด์ฉํ๋ฉด ์๋ฐ ์ค๋ ๋ API๋ณด๋ค ์ฝ๊ฒ ๋ณ๋ ฌ์ฑ์ ํ์ฉํ ์ ์๋ค.
1.3 ์๋ฐ ํจ์
๐ ๋ฉ์๋ ์ฐธ์กฐ
๋๋ ํฐ๋ฆฌ์์ ๋ชจ๋ ์จ๊ฒจ์ง ํ์ผ์ ํํฐ๋งํ๋ค๋ฉด, File ํด๋์ค์ isHidden ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- ์๋ฐ 8 ์ด์
- FileFilter ๊ฐ์ฒด๋ก isHidden ๋ฉ์๋๋ฅผ ๊ฐ์ผ ๋ค์์ File.listFiles ๋ฉ์๋๋ก ์ ๋ฌํด์ผ ํ๋ค.
File[] hiddenFiles = new File(".").listFiles(new FileFilter(){
public boolean accept(File file){
return file.isHidden(); // ์จ๊ฒจ์ง ํ์ผ ํํฐ๋ง
}
}
- ์๋ฐ 8
- ๋ฉ์๋ ์ฐธ์กฐ :: ๋ฌธ๋ฒ์ ์ด์ฉํด์ ์ง์ isHidden ํจ์๋ฅผ listFiles ๋ฉ์๋๋ก ์ ๋ฌํ ์ ์๋ค.
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
์์ฒ๋ผ ๊ธฐ์กด์ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ด์ฉํด์ ๊ฐ์ฒด๋ฅผ ์ฃผ๊ณ ๋ฐ์๋ ๊ฒ์ฒ๋ผ ์๋ฐ 8์์๋ File::isHidden์ ํตํด ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ๋ง๋ค์ด ์ ๋ฌํ ์ ์๊ฒ ๋์๋ค.
๐ Predicate
์ํ์์๋ ์ธ์๋ก ๊ฐ์ ๋ฐ์ true๋ false๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ํ๋ ๋์ผ์ดํธ๋ผ๊ณ ํ๋ค.
ํจ์ํ ์ธํฐํ์ด์ค Predicate๋ ์๋ฐ์์ ์ฃผ๋ก ๋๋ค ํํ์๊ณผ ํจ๊ป ์ฌ์ฉ๋์ด ํน์ ์กฐ๊ฑด์ ํ ์คํธํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. java.util.function ํจํค์ง์ ์ ์๋์ด ์์ผ๋ฉฐ, ์ ๋ ฅ๋ ๊ฐ์ฒด๊ฐ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ์ฌ๋ถ๋ฅผ ํ๊ฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. Predicate ์ธํฐํ์ด์ค๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ, ์ปฌ๋ ์ ์ ํํฐ๋ง, Stream API์ ํจ๊ป ์ฌ์ฉํ์ฌ ๋ณต์กํ ์กฐ๊ฑด ๋ก์ง์ ๊ฐ๊ฒฐํ๊ฒ ํํํ๋ ๋ฐ ์ ์ฉํ๋ค.
boolean test(T t) : ์ฃผ์ด์ง ๊ฐ์ฒด t๊ฐ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ํ๊ฐํ๋ค. ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด true, ๊ทธ๋ ์ง ์์ผ๋ฉด false๋ฅผ ๋ฐํํ๋ค.
Predicate<Integer> greaterThanTen = x -> x > 10;
Predicate<Integer> lessThanTwenty = x -> x < 20;
boolean result = greaterThanTen.test(15); // true ๋ฐํ
boolean result = greaterThanTen.and(lessThanTwenty).test(15); // true ๋ฐํ
๐ ๋๋ค : ์ต๋ช ํจ์
๋ฉ์๋๋ฅผ ๊ฐ์ผ๋ก ์ ๋ฌํ๋ ๊ธฐ๋ฅ์ ์ ์ฉํ์ง๋ง, ํ ๋๋ฒ๋ง ์ฌ์ฉํ ๋ฉ์๋๋ฅผ ๋งค๋ฒ ์ ์ํ๋ ๊ฒ์ ๊ท์ฐฎ์ ์ผ์ด๋ค. ๋ฐ๋ผ์ ์๋ฐ 8์์๋ ๋๋ค์ ๊ฐ๋ ์ ์ด์ฉํด์ ๊ตฌํํ๋ค.
(int x) → x + 1, ์ฆ, x๋ผ๋ ์ธ์๋ก ํธ์ถํ๋ฉด x+1์ ๋ฐํํ๋ ๋์์ ์ํํ๋๋ก ํ ์ ์๋ค. ์ด์ฒ๋ผ ๋๋ค ๋ฌธ๋ฒ ํ์์ผ๋ก ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ‘ํจ์ํ ํ๋ก๊ทธ๋๋ฐ, ์ฆ ํจ์๋ฅผ ๊ฐ์ผ๋ก ๋๊ฒจ์ฃผ๋ ํ๋ก๊ทธ๋จ์ ๊ตฌํํ๋ค’๊ณ ํ๋ค.
filter(inventory, (Apple a) -> a.getWeight < 80);
1.4 ์คํธ๋ฆผ API
์ปฌ๋ ์ API์์๋ ๋ฐ๋ณต ๊ณผ์ ์ ์ง์ ์ฒ๋ฆฌํด์ผ ํ๋ค. ์ฆ, for-each ๋ฃจํ๋ฅผ ์ด์ฉํด์ ๊ฐ ์์๋ฅผ ๋ฐ๋ณตํ๋ฉฐ ์์ ์ ์ํํ๋ค. (์ธ๋ถ ๋ฐ๋ณต)
๋ฐ๋ฉด, ์คํธ๋ฆผ API๋ฅผ ์ด์ฉํ๋ฉด ๋ฃจํ๋ฅผ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ด๋ถ์์ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ฒ๋ฆฌ๋๋ค. (๋ด๋ถ ๋ฐ๋ณต) ์คํธ๋ฆผ ๋ด์ ์์๋ฅผ ์ฝ๊ฒ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ์ ์๋ ํ๊ฒฝ์ ์ ๊ณตํ๋ค๋ ๊ฒ์ด ํต์ฌ์ด๋ค. ๋ฐ๋ผ์ ํํฐ๋งํ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ ์ปฌ๋ ์ ์ ์คํธ๋ฆผ์ผ๋ก ๋ฐ๊พธ๊ณ , ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌ(parallelStream())ํ ๋ค์์, ๋ฆฌ์คํธ๋ก ๋ค์ ๋ณต์ํ๋ ๊ฒ์ด๋ค.
- ์๋ฐ 8 ์ด์
// ๊ทธ๋ฃนํ๋ ํธ๋์ญ์
์ ๋ํ Map ์์ฑ
Map<Currency, List<Transaction>> transactionByCurrencies = new HashMap<>();
for(Transaction transaction : transactions){
if(transaction.getPrice() > 1000){ // ๊ณ ๊ฐ์ ํธ๋์ญ์
ํํฐ๋ง
// ํธ๋์ญ์
์ ํตํ ์ถ์ถ
Currency currency = transaction.getCurrency;
List<Transaction> transactionsForCurrency = transactionsByCurrencies.get(currency);
// ํ์ฌ ํตํ์ ๊ทธ๋ฃนํ๋ ๋งต์ ํญ๋ชฉ์ด ์์ผ๋ฉด ์๋ก ๋ง๋ ๋ค.
if(transactionsForCurrency == null){
transactionsForCurrency = new ArrayList<>();
transactionsByCurrencies.put(currency, transactionsForCurrency);
}
// ํ์ฌ ํ์๋ ํธ๋์ญ์
์ ๊ฐ์ ํตํ์ ํธ๋์ญ์
๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ค.
transactionsForCurrency.add(transaction);
}
}
}
- ์๋ฐ 8
Map<Currency, List<Transaction>> transactionByCurrencies
= transactions.stream()
// ๊ณ ๊ฐ์ ํธ๋์ญ์
ํํฐ๋ง
.filter((Transaction t) -> t.getPrice() > 1000)
// ํตํ๋ก ๊ทธ๋ฃนํ
.collect(groupingBy(Transaction::getCurrency));