item 45 dodo4513 - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
- ์คํธ๋ฆผ API๋ ๋ค๋์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ (์์ฐจ์ ์ด๋ ๋ณ๋ ฌ์ ์ด๋ )์ ๋๊ณ ์ ์๋ฐ 8์ ์ถ๊ฐ๋์๋ค.
- ์ด API๊ฐ ์ ๊ณตํ๋ ์ถ์ ๊ฐ๋
์ค ํต์ฌ์ ๋ ๊ฐ์ง๋ค.
- ๊ทธ ์ฒซ ๋ฒ์งธ์ธ ์คํธ๋ฆผ(stream)์ ๋ฐ์ดํฐ ์์์ ์ ํ ํน์ ๋ฌดํ ์ํ์ค(sequence)๋ฅผ ๋ปํ๋ค.
- ๋ ๋ฒ์งธ์ธ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ(stream pipeline)์ ์ด ์์๋ค๋ก ์ํํ๋ ์ฐ์ฐ ๋จ๊ณ๋ฅผ ํํํ๋ ๊ฐ๋ ์ด๋ค.
- ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์์ค ์คํธ๋ฆผ์์ ์์ํด ์ข ๋จ ์ฐ์ฐ(terminal operation)์ผ๋ก ๋๋๋ฉฐ, ๊ทธ ์ฌ์ด์ ํ๋ ์ด์์ ์ค๊ฐ ์ฐ์ฐ(intermediate operation)์ด ์์ ์ ์๋ค.
- ๊ฐ ์ค๊ฐ ์ฐ์ฐ์ ์คํธ๋ฆผ์ ์ด๋ ํ ๋ฐฉ์์ผ๋ก ๋ณํ(transform)ํ๋ค.
- ์ข ๋จ ์ฐ์ฐ์ ๋ง์ง๋ง ์ค๊ฐ ์ฐ์ฐ์ด ๋ด๋์ ์คํธ๋ฆผ์ ์ตํ์ ์ฐ์ฐ์ ๊ฐํ๋ค.
-
ํ๊ฐ๋ ์ข ๋จ ์ฐ์ฐ์ด ํธ์ถ๋ ๋ ์ด๋ค์ง๋ฉฐ
, ์ข ๋จ ์ฐ์ฐ์ ์ฐ์ด์ง ์๋ ๋ฐ์ดํฐ ์์๋ ๊ณ์ฐ์ ์ฐ์ด์ง ์๋๋ค. - ์ด๋ฌํ ์ง์ฐ ํ๊ฐ๊ฐ ๋ฌดํ ์คํธ๋ฆผ์ ๋ค๋ฃฐ ์ ์๊ฒ ํด์ฃผ๋ ์ด์ ๋ค.
- ์ข ๋จ ์ฐ์ฐ์ด ์๋ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์๋ฌด ์ผ๋ ํ์ง ์๋ ๋ช ๋ น์ด์ธ no-op๊ณผ ๊ฐ์ผ๋, ์ข ๋จ ์ฐ์ฐ์ ๋นผ๋จน๋ ์ผ์ด ์ ๋ ์๋๋ก ํ์.
- ์คํธ๋ฆผ API๋ ๋ฉ์๋ ์ฐ์๋ฅผ ์ง์ํ๋ ํ๋ฃจ์ธํธ API(fluent API)๋ค. ์ฆ, ํ์ดํ๋ผ์ธ ํ๋๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ ํธ์ถ์ ์ฐ๊ฒฐํ์ฌ ๋จ ํ๋์ ํํ์์ผ๋ก ์์ฑํ ์ ์๋ค
- ๊ธฐ๋ณธ์ ์ผ๋ก ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์์ฐจ์ ์ผ๋ก ์ํ๋๋ค. ํ์ดํ๋ผ์ธ์ ๋ณ๋ ฌ๋ก ์คํํ๋ ค๋ฉด ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ ์คํธ๋ฆผ ์ค ํ๋์์ parallel ๋ฉ์๋๋ฅผ ํธ์ถํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋, ํจ๊ณผ๋ฅผ ๋ณผ ์ ์๋ ์ํฉ์ ๋ง์ง ์๋ค
- ์คํธ๋ฆผ API๋ ๋ค์ฌ๋ค๋ฅํ์ฌ ์ฌ์ค์ ์ด๋ ํ ๊ณ์ฐ์ด๋ผ๋ ํด๋ผ ์ ์๋ค. ํ์ง๋ง ํ ์ ์๋ค๋ ๋ป์ด์ง, ํด์ผ ํ๋ค๋ ๋ป์ ์๋๋ค. ์คํธ๋ฆผ์ ์ ๋๋ก ์ฌ์ฉํ๋ฉด ํ๋ก๊ทธ๋จ์ด ์งง๊ณ ๊น๋ํด์ง์ง๋ง, ์๋ชป ์ฌ์ฉํ๋ฉด ์ฝ๊ธฐ ์ด๋ ต๊ณ ์ ์ง๋ณด์๋ ํ๋ค์ด ์ง๋ค.
// case1: ์คํธ๋ฆผ์ ์ฌ์ฉํ์ง ์์ ์ฝ๋
public class Anagrams {
public static void main(String[] args) throws IOException {
File dictionary = new File(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
Map<String, Set<String>> groups = new HashMap<>();
try (Scanner s = new Scanner(dictionary)) {
while (s.hasNext()) {
String word = s.next();
groups.computeIfAbsent(alphabetize(word),
(unused) -> new TreeSet<>()).add(word);
}
}
for (Set<String> group : groups.values())
if (group.size() >= minGroupSize)
System.out.println(group.size() + ": " + group);
}
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
}
- ๋งต์ ๊ฐ ๋จ์ด๋ฅผ ์ฝ์
ํ ๋ ์๋ฐ 8์์ ์ถ๊ฐ๋ computeIfAbsent ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
์ด์ฒ๋ผ computeIfAbsent๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ ํค์ ๋ค์์ ๊ฐ์ ๋งคํํ๋ ๋งต์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
// case2 ์คํธ๋ฆผ์ ๊ณผ๋ํ ์ฌ์ฉํ ์ฝ๋
public class Anagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(
groupingBy(word -> word.chars().sorted()
.collect(StringBuilder::new,
(sb, c) -> sb.append((char) c),
StringBuilder::append).toString()))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.map(group -> group.size() + ": " + group)
.forEach(System.out::println);
}
}
}
- ์ด ์ฝ๋๋ ํ์คํ ์งง์ง๋ง ์ฝ๊ธฐ๋ ์ด๋ ต๋ค. ํนํ ์คํธ๋ฆผ์ ์ต์ํ์ง ์์ ํ๋ก๊ทธ๋๋จธ๋ผ๋ฉด ๋์ฑ ๊ทธ๋ด ๊ฒ์ด๋ค. ์ด์ฒ๋ผ ์คํธ๋ฆผ์ ๊ณผ์ฉํ๋ฉด ํ๋ก๊ทธ๋จ์ด ์ฝ๊ฑฐ๋ ์ ์ง๋ณด์ํ๊ธฐ ์ด๋ ค์์ง๋ค.
// case3 ์ ๋นํ ์ ์ถฉ์ ์ฝ๋
public class Anagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(groupingBy(word -> alphabetize(word)))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.forEach(g -> System.out.println(g.size() + ": " + g));
}
}
// alphabetize ๋ฉ์๋๋ ์ฝ๋ 45-1๊ณผ ๊ฐ๋ค.
}
- ๋๋ค์์๋ ํ์ ์ด๋ฆ์ ์์ฃผ ์๋ตํ๋ฏ๋ก ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ ์ ์ง์ด์ผ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ๊ฐ๋ ์ฑ์ด ์ ์ง๋๋ค.
- ํํธ, ๋จ์ด์ ์ฒ ์๋ฅผ ์ํ๋ฒณ์์ผ๋ก ์ ๋ ฌํ๋ ์ผ์ ๋ณ๋ ๋ฉ์๋์ธ alphabetize์์ ์ํํ๋ค. ์ฐ์ฐ์ ์ ์ ํ ์ด๋ฆ์ ์ง์ด์ฃผ๊ณ ์ธ๋ถ ๊ตฌํ์ ์ฃผ ํ๋ก๊ทธ๋จ ๋ก์ง ๋ฐ์ผ๋ก ๋นผ๋ด ์ ์ฒด์ ์ธ ๊ฐ๋ ์ฑ์ ๋์ธ ๊ฒ์ด๋ค. ๋์ฐ๋ฏธ ๋ฉ์๋๋ฅผ ์ ์ ํ ํ์ฉํ๋ ์ผ์ ์ค์์ฑ์ ์ผ๋ฐ ๋ฐ๋ณต ์ฝ๋์์๋ณด๋ค๋ ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์์ ํจ์ฌ ํฌ๋ค.
-
์ฝ๋ ๋ธ๋ก์์๋ ๋ฒ์ ์์ ์ง์ญ๋ณ์๋ฅผ ์ฝ๊ณ ์์ ํ ์ ์๋ค. ํ์ง๋ง ๋๋ค์์๋ final์ด๊ฑฐ๋ ์ฌ์ค์ final์ธ ๋ณ์[JLS 4.12.4]๋ง ์ฝ์ ์ ์๊ณ , ์ง์ญ๋ณ์๋ฅผ ์์ ํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋ค.
-
์ฝ๋ ๋ธ๋ก์์๋ return ๋ฌธ์ ์ฌ์ฉํด ๋ฉ์๋์์ ๋น ์ ธ๋๊ฐ๊ฑฐ๋, break๋ continue ๋ฌธ์ผ๋ก ๋ธ๋ก ๋ฐ๊นฅ์ ๋ฐ๋ณต๋ฌธ์ ์ข ๋ฃํ๊ฑฐ๋ ๋ฐ๋ณต์ ํ ๋ฒ ๊ฑด๋๋ธ ์ ์๋ค. ๋ํ ๋ฉ์๋ ์ ์ธ์ ๋ช ์๋ ๊ฒ์ฌ ์์ธ๋ฅผ ๋์ง ์ ์๋ค. ํ์ง๋ง ๋๋ค๋ก๋ ์ด ์ค ์ด๋ค ๊ฒ๋ ํ ์ ์๋ค.
- ์์๋ค์ ์ํ์ค๋ฅผ ์ผ๊ด๋๊ฒ ๋ณํํ๋ค.
- ์์๋ค์ ์ํ์ค๋ฅผ ํํฐ๋งํ๋ค.
- ์์๋ค์ ์ํ์ค๋ฅผ ํ๋์ ์ฐ์ฐ์ ์ฌ์ฉํด ๊ฒฐํฉํ๋ค(๋ํ๊ธฐ, ์ฐ๊ฒฐํ๊ธฐ, ์ต์ ๊ฐ ๊ตฌํ๊ธฐ ๋ฑ).
- ์์๋ค์ ์ํ์ค๋ฅผ ์ปฌ๋ ์ ์ ๋ชจ์๋ค(์๋ง๋ ๊ณตํต๋ ์์ฑ์ ๊ธฐ์ค์ผ๋ก ๋ฌถ์ด๊ฐ๋ฉฐ).
- ์์๋ค์ ์ํ์ค์์ ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์๋ฅผ ์ฐพ๋๋ค.
- ํ ๋ฐ์ดํฐ๊ฐ ํ์ดํ๋ผ์ธ์ ์ฌ๋ฌ ๋จ๊ณ(stage)๋ฅผ ํต๊ณผํ ๋ ์ด ๋ฐ์ดํฐ์ ๊ฐ ๋จ๊ณ์์์ ๊ฐ๋ค์ ๋์์ ์ ๊ทผํ๊ธฐ๋ ์ด๋ ค์ด ๊ฒฝ์ฐ๋ค. ์คํธ๋ฆผ ํ์ดํ๋ผ์ธ์ ์ผ๋จ ํ ๊ฐ์ ๋ค๋ฅธ ๊ฐ์ ๋งคํํ๊ณ ๋๋ฉด ์๋์ ๊ฐ์ ์๋ ๊ตฌ์กฐ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์คํธ๋ฆผ์ ์ฌ์ฉํด์ผ ๋ฉ์ง๊ฒ ์ฒ๋ฆฌํ ์ ์๋ ์ผ์ด ์๊ณ , ๋ฐ๋ณต ๋ฐฉ์์ด ๋ ์๋ง์ ์ผ๋ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์๋ง์ ์์ ์ด ์ด ๋์ ์กฐํฉํ์ ๋ ๊ฐ์ฅ ๋ฉ์ง๊ฒ ํด๊ฒฐ๋๋ค.
์ด๋ ์ชฝ์ ์ ํํ๋ ํ๊ณ ๋ถ๋ํ ๊ท์น์ ์์ง๋ง ์ฐธ๊ณ ํ ๋งํ ์ง์นจ ์ ๋๋ ์๋ค.
์ด๋ ์ชฝ์ด ๋์์ง๊ฐ ํ์ฐํ ๋๋ฌ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ฒ ์ง๋ง, ์๋๋๋ผ๋ ๋ฐฉ๋ฒ์ ์๋ค.
์คํธ๋ฆผ๊ณผ ๋ฐ๋ณต ์ค ์ด๋ ์ชฝ์ด ๋์์ง ํ์ ํ๊ธฐ ์ด๋ ต๋ค๋ฉด ๋ ๋ค ํด๋ณด๊ณ ๋ ๋์ ์ชฝ์ ํํ๋ผ.