๐ซ ํค์ค์คํฌ ๊ณผ์ ๋ฅผ ๊ตฌํํ๋ฉฐ ๊ฒช์ ๋ฌธ์ ์ ๊ณผ ํด๊ฒฐ๋ฐฉ๋ฒ, ์๋ก ์๊ฒ๋ ์ ์ ๊ธฐ๋กํฉ๋๋ค.
์ฌ์ฉ์ ์ ํ์ Enum ์ ์ ๋ฐ ๊ฐ ์ฌ์ฉ์ ์ ํ์ ๋ฐ๋ฅธ ํ ์ธ์จ ์ ์ฉ
์ฃผ๋ฌธ ์, ์ฌ์ฉ์ ์ ํ์ ๋ง๋ ํ ์ธ์จ ์ ์ฉํด ์ด ๊ธ์ก์ ๊ณ์ฐํ๋ discount ๋ฉ์๋ ๊ตฌํ
public BigDecimal discount(BigDecimal price) {
return price.multiply(BigDecimal.valueOf(100 - discountPercent)
.divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
}
์ด ๊ธ์ก์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ๊ฐ ์ฌ์ฉ์ ์ ํ์ ๋ฐ๋ฅธ ํ ์ธ์จ(discountPercent)์ ์ ์ฉํ ๊ธ์ก์ ์์์ 2์๋ฆฌ ๋ฏธ๋งRoundingMode.DOWN(๋ด๋ฆผ)์ผ๋ก ์ค์ผ์ผ๋งํ์ฌ ๋ฐํํ๋ค.

ํ ์ธ์ด ์ ์ฉ๋์ง ์๋ '์ผ๋ฐ' ์ ํ ์ ํ ์, ๊ธ์ก์ด 8.900 ์ผ๋ก ๋ถํ์ํ 0์ด ๋ถ์ด์ ์ถ๋ ฅ๋์๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ฆฌํด ํ์
์ธ BigDecimal์ด ๋ฉ์๋๋ก ์ ๊ณตํ๋ค.
stripTrailingZeros() ๋ BigDecimal์ ๋ฉ์๋๋ก, ์ซ์์์ผ๋ก ๊ฐ์ด ๋์ผํ์ง๋ง ํํ์์ ํํ์ 0์ด ์ ๊ฑฐ๋ BigDecimal์ ๋ฐํํ๋ ๋ฉ์๋์ด๋ค.
public BigDecimal discount(BigDecimal price) {
return price.multiply(BigDecimal.valueOf(100 - discountPercent)
.divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN))
.stripTrailingZeros();
}

๐ stripTrailingZeros()์ ๋ฐํ๊ฐ์ผ๋ก ์์์ ์๋์ ๋ถํ์ํ 0์ด ์ฌ๋ผ์ง ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ปฌ๋ ์ ์ ์๋ฐ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ํ๋ ์์ํฌ์ด๋ฉฐ, ์คํธ๋ฆผ์ ์๋ฐ 8๋ถํฐ ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ผ๋ก ์ปฌ๋ ์ ์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ํจ์ํ ์คํ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ค๋ค.
์ฐ์๋ ๋ฐ์ดํฐ๋ฅผ ์ํํ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ ๋ฐ๋ณต๋ฌธ forEach()๊ฐ ์๋ค.
์๋ฐ์์ ์ฐ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๋ ์ปฌ๋ ์
๊ณผ ์คํธ๋ฆผ ๋ ๋ค forEach๋ฅผ ์ง์ํ๋ค.
์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธด ๋ชจ๋ ๋ฉ๋ด๋ฅผ ์ถ๋ ฅํ๋ printCart()๋ฅผ Collection.forEach() ์ stream.forEach() ๋ก ์์ฑํ๊ณ ๋น๊ตํด๋ณด์.
cartItems.entrySet().stream().forEach(entry -> System.out.printf("%-21s | W %4.1f | %s%n",
entry.getKey().getName(),
BigDecimal.valueOf(entry.getValue() * entry.getKey().getPrice()),
entry.getKey().getDescription()));
cartItems.forEach((key, value) -> System.out.printf("%-21s | W %4.1f | %s%n",
key.getName(),
BigDecimal.valueOf(value * key.getPrice()),
key.getDescription()));
๐ก Map์ Collection์ ์์๋ฐ์ง ์๋๋ค. ์์์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์ Collection์ default ๋ฉ์๋์ธ stream()์ ์ธ ์ ์๋ค.โ
Map.stream()์ ๋ถ๊ฐ๋ฅ
๋ค๋ง, Map์ ๊ตฌ์กฐ์์ ์ฐจ์ด(Key-Value)๋ง ์์ ๋ฟ ์ญํ ๊ณผ ๊ธฐ๋ฅ์ด Collection๊ณผ ์ ์ฌํ๋ฏ๋ก ์ปฌ๋ ์ ํ๋ ์์ํฌ๋ก ๊ฐ์ด ๋ฌถ์ฌ์๋ค.

๐ ์์ ๋ ์ฝ๋๋ ๊ฐ์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ์ง๋ง stream().forEach()๋ก ์์ฑํ ์ฝ๋์๋ IDE๊ฐ forEach()๋ก ๋์ฒดํ๋ผ๊ณ ๊ถํ๋ค.
์์ ๋ณด์ฅ: stream์ ๊ฒฝ์ฐ, ๋ณ๋ ฌ ์คํธ๋ฆผ(parallelStream)์ ์ฌ์ฉํ๋ฉด ์์ฑ๋ stream์ ์์๋ฅผ ๋ณด์ฅํ์ง ์๋๋ค.Exception: Collection์ forEach์ ๊ฒฝ์ฐ ์ํ ์ค ๋์ collection์ ๊ฐ์ ๋ณ๊ฒฝ์ด ์๊ธฐ๋ฉด ๋ฐ๋ก ์์ธ๋ฅผ ๋์ง๋ค.๊ฐ๋ฅํ๋ฉด stream.forEach()๋ณด๋ค collection.forEach()๋ฅผ ์ฌ์ฉํ์.
์ด๋ฒ์๋ ๊ธฐ์กด ์ฅ๋ฐ๊ตฌ๋์์ ํน์ ๋ฉ๋ด ๋นผ๊ธฐ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด์.


๐ ํ์ด๋ผ์ดํธ๋ ์ฝ๋๋ ๊ฐ์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ์ง๋ง, removeIf()๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ ํ ์ค๋ก ์ฒ๋ฆฌํ ์ ์๋ค.

Collection์ด ์ ๊ณตํ๋ default ๋ฉ์๋์ด๊ณ , ํํฐ๋ง ์ญํ ์ ํ๋ ํจ์ํ ์ธํฐํ์ด์ค Predicate๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
โ Predicate: ๋งค๊ฐ๊ฐ์ด ์กฐ๊ฑด์ ๋ง๋์ง ๋จ์ ํ์ฌ boolean ๋ฐํ
(= ๊ฒฐ๊ณผ๊ฐ boolean ์ธ ์ต๋ช
ํจ์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ ์ ์๋ค.)
forEach()์ removeIf() ๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ stream๋ณด๋ค Collection์ด ์ ๊ณตํ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ ๋ ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋ ์ข๋ค. (๋ฌผ๋ก , ๊ฐ๋ ์ฑ์ ๊ฐ์ธ๋ง๋ค ์ฒด๊ฐ์ด ๋ค๋ฅผ ์ ์๋ค.)