๐ 1. ํจ์ํ ์ธํฐํ์ด์ค
์๋ฐ๊ฐ ๋๋ค๋ฅผ ์ง์ํ๋ฉด์ ์์ ํด๋์ค์ ๊ธฐ๋ณธ ๋ฉ์๋๋ฅผ ์ฌ์ ์ํด ์ํ๋ ๋์์ ๊ตฌํํ๋ ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด์ ๋งค๋ ฅ์ด ํฌ๊ฒ ์ค์๋ค.
์ด๋ฅผ ๋์ฒดํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํจ์ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ ์ ์ ํฉํฐ๋ฆฌ๋ ์์ฑ์๋ฅผ ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์ฆ, ํจ์ ๊ฐ์ฒด๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๋ ์์ฑ์์ ๋ฉ์๋๋ฅผ ๋ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
LinkedHashMap์ removeEldestEntry๋ฅผ ์ดํด๋ณด์. removeEldestEntry๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ ์ํ๋ฉด, ๋งต์ ์์๊ฐ 100๊ฐ๊ฐ ๋ ๋๋ง๋ค ๊ฐ์ฅ ์ค๋๋ ์์๋ฅผ ํ๋์ฉ ์ ๊ฑฐํ๋ค.
// ๊ธฐ์กด
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
...
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
...
}
// ์ฌ์ ์
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > 100;
}
์ด๋ฅผ ํจ์ํ ์ธํฐํ์ด์ค๋ก ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
@FunctionalInterface
interface EldestEntryRemovalFunction<K, V> {
boolean remove(Map<K, V> map, Map.Entry<K, V> eldest);
}
ํ์ง๋ง, ๊ตณ์ด ๋ถํ์ํ๊ฒ ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค ํ์๋ ์๋ค.
ํ์ค ์ธํฐํ์ด์ค์ธ BiPredicate<Map<K, V>, Map.Entry<K, V>>๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๐ 2. ํ์ค ํจ์ํ ์ธํฐํ์ด์ค
java.util.function ํจํค์ง๋ฅผ ๋ณด๋ฉด ๋ค์ํ ์ฉ๋์ ํ์ค ํจ์ํ ์ธํฐํ์ด์ค๊ฐ ๋ด๊ฒจ ์๋ค.
๊ทธ๋ฌ๋ฏ๋ก ํ์ค ํจ์ํ ์ธํฐํ์ด์ค์ ํ์ํ ์ฉ๋์ ๋ง๋ ๊ฒ ์๋ค๋ฉด, ์ง์ ๊ตฌํํ์ง ๋ง๊ณ ํ์ค ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํ๋๋ก ํ์.
์ด 43๊ฐ์ ํ์ค ํจ์ํ ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํ๋๋ฐ, ๊ธฐ๋ณธ ์ธํฐํ์ด์ค 6๊ฐ๋ง ๊ธฐ์ตํ๋ฉด ๋๋จธ์ง๋ ์ถฉ๋ถํ ์ ์ถํ ์ ์๋ค. ๊ธฐ๋ณธ ์ธํฐํ์ด์ค 6๊ฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- Operator ์ธํฐํ์ด์ค
๋ฐํ๊ฐ๊ณผ ์ธ์์ ํ์ ์ด ๊ฐ์ ํจ์
์ธ์๊ฐ 1๊ฐ์ธ UnaryOperator์ 2๊ฐ์ธ BinaryOperator๊ฐ ์๋ค. - Predicate ์ธํฐํ์ด์ค
์ธ์ ํ๋๋ฅผ ๋ฐ์ boolean์ ๋ฐํํ๋ ํจ์ - Funtion ์ธํฐํ์ด์ค
์ธ์์ ๋ฐํ ํ์ ์ด ๋ค๋ฅธ ํจ์ - Supplier ์ธํฐํ์ด์ค
์ธ์๋ฅผ ๋ฐ์ง ์๊ณ ๊ฐ์ ๋ฐํ(ํน์ ์ ๊ณต)ํ๋ ํจ์ - Consumer ์ธํฐํ์ด์ค
์ธ์๋ฅผ ํ๋ ๋ฐ๊ณ ๋ฐํ๊ฐ์ ์๋(ํนํ ์ธ์๋ฅผ ์๋นํ๋) ํจ์
์ธํฐํ์ด์ค | ํจ์ ์๊ทธ๋์ฒ | ์ |
UnaryOperator<T> | T apply(T t) | String::toLowerCase |
BinaryOperator<T> | T apply(T t1, T t2) | BigInteger::add |
Predicate<T> | boolean test(T t) | Collection::isEmpty |
Function<T, R> | R apply(T t) | Arrays::asList |
Supplier<T> | T get() | Instant::now |
Consumer<T> | void accept(T t) | System.out::println |
ํ์ค ํจ์ํ ์ธํฐํ์ด์ค๋ ๋๋ถ๋ถ ๊ธฐ๋ณธ ํ์ ๋ง ์ง์ํ๋ค. ๊ทธ๋ ๋ค๊ณ ๊ธฐ๋ณธ ํจ์ํ ์ธํฐํ์ด์ค์ ๋ฐ์ฑ ๋ ๊ธฐ๋ณธ ํ์ ์ ๋ฃ์ด ์ฌ์ฉํ์ง๋ ๋ง์. ๊ณ์ฐ๋์ด ๋ง์ ๋ ์ฑ๋ฅ์ด ๋งค์ฐ ๋๋ ค์ง ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๐ 3. ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ ์๊ธฐ ๋ฐ ์์ฑ๋ฒ
๐ 1. ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ ์๊ธฐ
์๋์ 3๊ฐ์ง ๊ฒฝ์ฐ ์ค ํ๋ ์ด์์ ๋ง์กฑํ๋ค๋ฉด ์ ์ฉ ํจ์ํ ์ธํฐํ์ด์ค ๊ตฌํ์ ๊ณ ๋ฏผํด ๋ณด์.
- ์์ฃผ ์ฐ์ด๋ฉฐ, ์ด๋ฆ ์์ฒด๊ฐ ์ฉ๋๋ฅผ ๋ช ํํ ์ค๋ช ํด ์ค๋ค.
- ๋ฐ๋์ ๋ฐ๋ผ์ผ ํ๋ ๊ท์ฝ์ด ์๋ค.
- ์ ์ฉํ ๋ํดํธ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค.
์ด๋ฅผ ์ ๋ํ๋ด๋ ์์๊ฐ Comparator<T> ์ธํฐํ์ด์ค๋ค. ๊ตฌ์กฐ์ ์ผ๋ก ToIntBiFunction<T, U>์ ๋์ผํ๋ค.
ํ์ง๋ง ์๋์ ๋ด์ฉ๋ค๋ก ์ธํด ๋ ์์ ์ธ ์ธํฐํ์ด์ค๋ก ์ด์๋จ๊ฒ ๋์๋ค.
- API์์ ๊ต์ฅํ ์์ฃผ ์ฌ์ฉ๋๋๋ฐ, ์ง๊ธ์ ์ด๋ฆ์ด ๊ทธ ์ฉ๋๋ฅผ ์์ฃผ ํ๋ฅญํ ์ค๋ช ํ๋ค.
- ๊ตฌํํ๋ ์ชฝ์์ ๋ฐ๋์ ์ง์ผ์ผ ํ ๊ท์ฝ์ ๋ด๊ณ ์๋ค.
- ๋น๊ต์๋ค์ ๋ณํํ๊ณ ์กฐํฉํด ์ฃผ๋ ์ ์ฉํ ๋ํดํธ ๋ฉ์๋๋ค์ ๋ด๊ณ ์๋ค.
๐ 2. ์์ฑ๋ฒ
์ง์ ๋ง๋ ํจ์ํ ์ธํฐํ์ด์ค์๋ ํญ์ @FunctionalInterface ์ ๋ํ ์ด์ ์ ๋ฌ๋๋ก ํ์. ์ด๋ @Override์ฒ๋ผ ํ๋ก๊ทธ๋๋จธ์ ์๋๋ฅผ ๋ช ์ํ๋ ์ญํ ์ ํ๋ค.
๊ทธ ๋ชฉ์ ์ ์๋์ ๊ฐ๋ค.
- ํด๋น ํด๋์ค์ ์ฝ๋๋ ์ค๋ช ๋ฌธ์๋ฅผ ์ฝ์ ์ด์๊ฒ ๊ทธ ์ธํฐํ์ด์ค๊ฐ ๋๋ค์ฉ์ผ๋ก ์ค๊ณ๋ ๊ฒ์์ ์๋ ค์ค๋ค.
- ํด๋น ์ธํฐํ์ด์ค๊ฐ ์ถ์ ๋ฉ์๋๋ฅผ ์ค์ง ํ๋๋ง ๊ฐ์ง๊ณ ์์ด์ผ ์ปดํ์ผ๋๊ฒ ํด์ค๋ค.
- ์ ์ง๋ณด์ ๊ณผ์ ์์ ๋๊ตฐ๊ฐ ์ค์๋ก ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ง ๋ชปํ๋๋ก ํด์ค๋ค.
๐ 4. ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ API์์ ์ฌ์ฉํ ๋์ ์ฃผ์์
ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ API์์ ์ฌ์ฉํ ๋์ ์ฃผ์์ ์ ๋ํด์ ์ดํด๋ณด์.
์๋ก ๋ค๋ฅธ ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ ์์น์ ์ธ์๋ก ๋ฐ๋ ๋ฉ์๋๋ค์ ๋ค์ค ์ ์ํด์๋ ์ ๋๋ค.
ExecutorService์ submit ๋ฉ์๋๋ Callable<T>๋ฅผ ๋ฐ๋ ๊ฒ๊ณผ Runnable์ ๋ฐ๋ ๊ฒ์ ๋ค์ค์ ์ํ๋ค.
public interface ExecutorService extends Executor {
...
<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
...
}
๊ทธ ๊ฒฐ๊ณผ, ์ฌ๋ฐ๋ฅธ ๋ฉ์๋๋ฅผ ์๋ ค์ฃผ๊ธฐ ์ํด ํ๋ณํ์ ํด์ผ ํ ๋๊ฐ ๋งค์ฐ ๋ง์ด ์๊ธฐ๊ฒ ๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์๋ก ๋ค๋ฅธ ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ ์์น์ ์ธ์๋ก ์ฌ์ฉํ๋ ๋ค์ค ์ ์๋ฅผ ํ์ง ๋ง๋๋ก ํ์.
ํด๋น ๊ธ์ Joshua Bloch ๋์ 'Effective Java 3/E'๋ฅผ ์ฐธ๊ณ ํ์์ต๋๋ค.