item 52 junghyunlyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
λ€μμ 컬λ μ μ μ§ν©, 리μ€νΈ, κ·Έ μΈλ‘ ꡬλΆνκ³ μ λ§λ νλ‘κ·Έλ¨μ΄λ€.
public class CollectionClassifier {
public static String classify(Set<?> s) {
return "μ§ν©";
}
public static String classify(List<?> lst) {
return "리μ€νΈ";
}
public static String classify(Collection<?> c) {
return "κ·Έ μΈ";
}
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<BigInteger>(),
new HashMap<String, String>().values()
};
for (Collection<?> c : collections)
System.out.println(classify(c));
}
}
"μ§ν©", "리μ€νΈ", "κ·Έ μΈ"λ₯Ό μ°¨λ‘λ‘ μΆλ ₯ν κ² κ°μ§λ§, μ€μ λ‘ μνν΄λ³΄λ©΄ "κ·Έ μΈ"λ§ μΈλ² μ°λ¬μ μΆλ ₯νλ€.
μλνλ©΄ λ€μ€μ μλ μΈ classify μ€ μ΄λ λ©μλλ₯Ό νΈμΆν μ§κ° μ»΄νμΌνμμ μ ν΄μ§κΈ° λλ¬Έμ΄λ€.
μ»΄νμΌνμμλ for λ¬Έ μμ cλ νμ Collection<?> νμ μ΄λ€.
λ°νμμλ νμ μ΄ λ§€λ² λ¬λΌμ§μ§λ§, νΈμΆν λ©μλλ₯Ό μ ννλ λ°λ μν₯μ μ£Όμ§ λͺ»νλ€.
λ°λΌμ μ»΄νμΌνμμ 맀κ°λ³μ νμ μ κΈ°μ€μΌλ‘ νμ μΈ λ²μ§Έ λ©μλμΈ classify(Collection<?>)λ§ νΈμΆνλ κ²μ΄λ€.
μ΄μ²λΌ μ§κ΄κ³Ό μ΄κΈλλ μ΄μ λ μ¬μ μν λ©μλλ λμ μΌλ‘ μ νλκ³ , λ€μ€μ μν λ©μλλ μ μ μΌλ‘ μ νλκΈ° λλ¬Έμ΄λ€.
λ©μλλ₯Ό μ¬μ μνλ€λ©΄ ν΄λΉ κ°μ²΄μ λ°νμ νμ μ΄ μ΄λ€ λ©μλλ₯Ό νΈμΆν μ§μ κΈ°μ€μ΄ λλ€.
μ»΄νμΌνμμ κ·Έ μΈμ€ν΄μ€μ νμ μ΄ λ¬΄μμ΄μλλ μκ΄μλ€. λ€μ μ½λλ μ΄λ¬ν μν©μ ꡬ체μ μΌλ‘ 보μ¬μ€λ€.
public class Overriding {
public static void main(String[] args) {
List<Wine> wineList = List.of(
new Wine(), new SparklingWine(), new Champagne());
for (Wine wine : wineList)
System.out.println(wine.name());
}
}
Wine ν΄λμ€μ μ μλ name λ©μλλ νμ ν΄λμ€μΈ SparklingWineκ³Ό Champagneμμ μ¬μ μλλ€.
μμν κ²μ²λΌ μ΄ νλ‘κ·Έλ¨μ "ν¬λμ£Ό", "λ°ν¬μ± ν¬λμ£Ό", "μ΄νμΈ" μ μ°¨λ‘λ‘ μΆλ ₯νλ€.
CollectionClassifierμμμ μ»΄νμΌνμ λ€μ€μ μ λ©μλ κ²°μ λ¬Έμ λ λͺ¨λ classify λ©μλλ₯Ό νλλ‘ ν©μΉ ν instanceofλ‘ λͺ μμ μΌλ‘ κ²μ¬νλ©΄ λ§λν ν΄κ²°λλ€.
public static String classify(Collection<?> c) {
return c instanceof Set ? "μ§ν©" :
c instanceof List ? "리μ€νΈ" : "κ·Έ μΈ";
}
κ°λ°μμκ²λ μ¬μ μκ° μ μμ μΌλ‘ 보μ΄κ³ , λ€μ€μ μκ° μμΈμ μΌλ‘ λ³΄μΌ μ μλ€.
μ¦, μ¬μ μν λ©μλλ κ°λ°μκ° κΈ°λν λλ‘ λμνμ§λ§, CollectionClassifier μμμ μ²λΌ λ€μ€μ μν λ©μλλ μ΄λ¬ν κΈ°λλ₯Ό κ°λ³κ² 무μνλ€.
ν·κ°λ¦΄ μ μλ μ½λλ μμ±νμ§ μλ κ² μ’λ€. νΉνλ κ³΅κ° APIλΌλ©΄ λμ± μ κ²½ μ¨μΌ νλ€. λ€μ€μ μκ° νΌλμ μΌμΌν€λ μν©μ μ΅λν νΌν΄μΌ νλ€.
μ νν μ΄λ»κ² μ¬μ©νμ λ λ€μ€μ μκ° νΌλμ μ£Όλλμ λν΄μλ λ Όλμ μ¬μ§κ° μλ€.
μμ νκ³ λ³΄μμ μΌλ‘ κ°λ €λ©΄ 맀κ°λ³μ μκ° κ°μ λ€μ€μ μλ λ§λ€μ§ λ§μ.
κ°λ³μΈμλ₯Ό μ¬μ©νλ λ©μλλΌλ©΄ λ€μ€μ μλ₯Ό μμ νμ§ λ§μμΌ νλ€. (item 53)
λ€μ€μ μνλ λμ λ©μλ μ΄λ¦μ λ€λ₯΄κ² μ§μ΄μ£Όλ κΈΈμ νμ μ΄λ €μλ€.
ObjectOutPutStream ν΄λμ€μ κ²½μ°λ₯Ό μ΄ν΄λ³΄μ. μ΄ ν΄λμ€μ write λ©μλλ λͺ¨λ κΈ°λ³Έ νμ κ³Ό μΌλΆ μ°Έμ‘° νμ μ© λ³νμ κ°μ§κ³ μλ€.
κ·Έλ°λ° λ€μ€μ μκ° μλ, λͺ¨λ λ©μλμ λ€λ₯Έ μ΄λ¦μ μ§μ΄μ£Όλ κΈΈμ ννλ€. writeBoolean(boolea), writeInt(int), writeLong(long) μ²λΌ.
μ΄ λ°©μμ μ₯μ μ read λ©μλμ μ΄λ¦κ³Ό μ§μ λ§μΆκΈ° μ’λ€λ μ μ΄λ€. readBoolean(), readInt(), readLong() μ²λΌ.
μ€μ λ‘λ μ΄λ κ² λμ΄ μλ€.
ννΈ, μμ±μλ μ΄λ¦μ λ€λ₯΄κ² μ§μ μ μμΌλ λ λ²μ§Έ μμ±μλΆν°λ 무쑰건 λ€μ€μ μκ° λλ€.
νμ§λ§ μ μ ν©ν°λ¦¬λΌλ λμμ νμ©ν μ μλ κ²½μ°κ° λ§λ€. (item 1) λν μμ±μλ μ¬μ μν μ μμΌλ λ€μ€μ μμ μ¬μ μκ° νΌμ©λ κ±±μ μ νμ§ μμλ λλ€.
κ·Έλλ μ¬λ¬ μμ±μκ° κ°μ μμ 맀κ°λ³μλ₯Ό λ°μμΌ νλ κ²½μ°λ₯Ό μμ ν νΌν΄κ° μλ μμΌλ, κ·Έλ΄ λλ₯Ό λλΉν΄ μμ λμ± μ λ°°μλλ©΄ λμμ΄ λ κ²μ΄λ€.
맀κ°λ³μκ° κ°μ λ€μ€μ μ λ©μλκ° λ§λλΌλ, κ·Έμ€ μ΄λ κ²μ΄ μ£Όμ΄μ§ 맀κ°λ³μ μ§ν©μ μ²λ¦¬ν μ§κ° λͺ νν ꡬλΆλλ€λ©΄ ν·κ°λ¦΄ μΌμ μμ κ²μ΄λ€.
μ¦, 맀κ°λ³μ μ€ νλ μ΄μμ΄ "κ·Όλ³Έμ μΌλ‘ λ€λ₯΄λ€"λ©΄ ν·κ°λ¦΄ μΌμ΄ μλ€.
κ·Όλ³Έμ μΌλ‘ λ€λ₯΄λ€λ κ²μ nullμ΄ μλ λ νμ
μ κ°μ μλ‘ μ΄λ μͺ½μΌλ‘λ νλ³νν μ μλ€λ λ»μ΄λ€.
μ΄ μ‘°κ±΄λ§ μΆ©μ‘±νλ©΄ μ΄λ λ€μ€μ μ λ©μλλ₯Ό νΈμΆν μ§κ° 맀κ°λ³μλ€μ λ°νμ νμ λ§μΌλ‘ κ²°μ λλ€.
λ°λΌμ μ»΄νμΌνμ νμ μλ μν₯μ λ°μ§ μκ² λκ³ , νΌλμ μ£Όλ μ£Όλ μμΈμ΄ μ¬λΌμ§λ€.
μλ° 4κΉμ§λ λͺ¨λ κΈ°λ³Έ νμ μ΄ λͺ¨λ μ°Έμ‘° νμ κ³Ό κ·Όλ³Έμ μΌλ‘ λ¬λμ§λ§, μλ° 5μμ μ€ν λ°μ±μ΄ λμ λλ©΄μ ννλ‘λ μλκ° λ§μ λ΄λ Έλ€.
λ€μ νλ‘κ·Έλ¨μ μ΄ν΄λ³΄μ.
public class SetList {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
List<Integer> list = new ArrayList<>();
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
System.out.println(set + " " + list);
}
}
μ΄ νλ‘κ·Έλ¨μ -3λΆν° 2κΉμ§μ μ μλ₯Ό μ λ ¬λ μ§ν©κ³Ό 리μ€νΈμ κ°κ° μΆκ°ν λ€μ, μμͺ½μ λκ°μ΄ remove λ©μλλ₯Ό μΈ λ² νΈμΆνλ€.
κ·Έλ¬λ©΄ μ΄ νλ‘κ·Έλ¨μ μμ΄ μλ κ°, μ¦ 0, 1, 2λ₯Ό μ κ±°ν ν "[-3, -2, -1] [-3, -2, -1]" μ μΆλ ₯νλ¦¬λΌ μμν κ²μ΄λ€.
νμ§λ§ μ€μ λ‘λ μ§ν©μμλ μμ΄ μλ κ°μ μ κ±°νκ³ , 리μ€νΈμμλ νμλ₯Ό μ κ±°ν ν "[-3, -2, -1] [-2, 0, 2]" λ₯Ό μΆλ ₯νλ€. λ¬΄μ¨ μΌμΌκΉ?
set.remove(i)μ μκ·Έλμ²λ remove(Object)λ€. λ€μ€μ μλ λ€λ₯Έ λ©μλκ° μμΌλ κΈ°λν λλ‘ λμνμ¬ μ§ν©μμ 0 μ΄μμ μλ€μ μ κ±°νλ€.
ννΈ, list.remove(i)λ λ€μ€μ μλ remove(int index)λ₯Ό μ ννλ€.
κ·Έλ°λ° μ΄ removeλ 'μ§μ ν μμΉ'μ μμλ₯Ό μ κ±°νλ κΈ°λ₯μ μννλ€!
μ΄ λ¬Έμ λ list.removeμ μΈμλ₯Ό Integerλ‘ νλ³ννμ¬ μ¬λ°λ₯Έ λ€μ€μ μ λ©μλλ₯Ό μ ννκ² νλ©΄ ν΄κ²°λλ€.
νΉμ Integer.valueOfλ₯Ό μ΄μ©ν΄ iλ₯Ό Integerλ‘ λ³νν ν list.removeμ μ λ¬ν΄λ λλ€.
μλ° 8μμ λμ ν λλ€μ λ©μλ μ°Έμ‘° μμ λ€μ€μ μ μμ νΌλμ ν€μ λ€.
new Thread(System.out::println).start();
Executors.newCachedThreadPool().submit(System.out::println);
2λ²λ§ μ»΄νμΌ μ€λ₯κ° λλ€. λκ²¨μ§ μΈμλ λͺ¨λ System.out::printlnμΌλ‘ λκ°κ³ , μμͺ½ λͺ¨λ Runnableμ λ°λ νμ λ©μλλ₯Ό λ€μ€μ μνκ³ μλ€.
κ·Έλ°λ° μ νμͺ½λ§ μ€ν¨ν κΉ? μμΈμ λ°λ‘ submit λ€μ€ μ μ λ©μλ μ€μλ Callableλ₯Ό λ°λ λ©μλλ μλ€λ λ° μλ€.
<T> Future<T> submit(Callable<T> task);
νμ§λ§ λͺ¨λ printlnμ΄ voidλ₯Ό λ°ννλ, λ°νκ°μ΄ μλ Callableκ³Ό ν·κ°λ¦΄ 리λ μλ€κ³ μκ°ν μ§λ λͺ¨λ₯Έλ€.
ν©λ¦¬μ μΈ μΆλ‘ μ΄μ§λ§, λ€μ€μ μ ν΄μ(resolution : μ μ ν λ€μ€μ μ λ©μλλ₯Ό μ°Ύλ μκ³ λ¦¬μ¦)λ μ΄λ κ² λμνμ§ μλλ€.
λ§μ½ printlnμ΄ λ€μ€μ μ μμ΄ λ¨ νλλ§ μ‘΄μ¬νλ€λ©΄ μ΄ submit λ©μλ νΈμΆμ΄ μ λλ‘ μ»΄νμΌλμ κ²μ΄λ€.
μ§κΈμ μ°Έμ‘°λ λ©μλμ νΈμΆν λ©μλ μμͺ½ λ€ λ€μ€μ μλμ΄, λ€μ€μ μ ν΄μ μκ³ λ¦¬μ¦μ΄ μ°λ¦¬μ κΈ°λμ²λΌ λμνμ§ μλ μν©μ΄λ€.
κΈ°μ μ μΌλ‘ λ§νλ©΄ System.out::printlnμ λΆμ νν λ©μλ μ°Έμ‘°λ€.
κ·Έλ¦¬κ³ λΆμ νν λ©μλ μ°Έμ‘°κ°μ μΈμ ννμμ λͺ©ν νμ μ΄ μ νλκΈ° μ μλ κ·Έ μλ―Έκ° μ ν΄μ§μ§ μκΈ° λλ¬Έμ μ μ©μ± ν μ€νΈ(??) λ 무μλλ€.
λ§μ΄ μ΄λ €μ΄λ°, ν΅μ¬μ λ€μ€μ μλ λ©μλ(or μμ±μ)λ€μ΄ ν¨μν μΈν°νμ΄μ€λ₯Ό μΈμλ‘ λ°μ λ, λΉλ‘ μλ‘ λ€λ₯Έ ν¨μν μΈν°νμ΄μ€λΌλ μΈμ μμΉκ° κ°μΌλ©΄ νΌλμ΄ μκΈ΄λ€λ κ²μ΄λ€.
λ°λΌμ λ©μλλ₯Ό λ€μ€μ μν λ, μλ‘ λ€λ₯Έ ν¨μν μΈν°νμ΄μ€λΌλ κ°μ μμΉμ μΈμλ‘ λ°μμλ μ λλ€.
μ΄ λ§μ μλ‘ λ€λ₯Έ ν¨μν μΈν°νμ΄μ€λΌλ μλ‘ κ·Όλ³Έμ μΌλ‘ λ€λ₯΄μ§ μλ€λ λ»μ΄λ€.
μ»΄νμΌν λ λͺ λ Ήμ€ μ€μμΉλ‘ -Xlint:overloads λ₯Ό μ§μ νλ©΄ μ΄λ° μ’ λ₯μ λ€μ€μ μλ₯Ό κ²½κ³ ν΄μ€ κ²μ΄λ€.
Object μΈμ ν΄λμ€ νμ κ³Ό λ°°μ΄ νμ μ κ·Όλ³Έμ μΌλ‘ λ€λ₯΄λ€. Serializableκ³Ό Cloneable μΈμ μΈν°νμ΄μ€ νμ κ³Ό λ°°μ΄ νμ λ κ·Όλ³Έμ μΌλ‘ λ€λ₯΄λ€.
ννΈ, Stringκ³Ό Throwableμ²λΌ μμ/νμ κ΄κ³κ° μλ λ ν΄λμ€λ 'κ΄λ ¨ μλ€' κ³ νλ€.
κ·Έλ¦¬κ³ μ΄λ€ κ°μ²΄λ κ΄λ ¨ μλ λ ν΄λμ€μ κ³΅ν΅ μΈμ€ν΄μ€κ° λ μ μκΈ°μ, κ΄λ ¨ μλ ν΄λμ€λ€λΌλ¦¬λ κ·Όλ³Έμ μΌλ‘ λ€λ₯΄λ€.
μ΄ μΈμλ μ΄λ€ λ°©ν₯μΌλ‘λ νλ³νν μ μλ νμ μμ΄ μμ§λ§, μ΄μ¨λ μμμ λμ΄ν κ°λ¨ν μλ³΄λ€ λ³΅μ‘ν΄μ§λ©΄ λλΆλΆ νλ‘κ·Έλλ¨Έλ μ΄λ€ λ€μ€μ μ λ©μλκ° μ νλ μ§λ₯Ό ꡬλΆνκΈ° μ΄λ €μν κ²μ΄λ€.
λ€μ€μ μλ λ©μλ μ€ νλλ₯Ό μ ννλ κ·μΉμ λ§€μ° λ³΅μ‘νλ©°, μλ°κ° λ²μ μ λ μλ‘ λ 볡μ‘ν΄μ§κ³ μμ΄, μ΄ λͺ¨λλ₯Ό μ΄ν΄νκ³ μ¬μ©νλ νλ‘κ·Έλλ¨Έλ κ·Ήν λλ¬Ό κ²μ΄λ€.
μ΄λ² μμ΄ν μμ μ€λͺ ν μ§μΉ¨λ€μ μ§ν€μ§ λͺ»ν μλ μλ€. μ΄λ―Έ λ§λ€μ΄μ§ ν΄λμ€κ° λΌμ΄λ€λ©΄ νΉν λ κ·Έλ λ€.
μλ₯Ό λ€μ΄ Stringμ μλ° 4 μμ λΆν° ContentEquals(StringBuffer) λ©μλλ₯Ό κ°μ§κ³ μμλ€.
κ·Έλ°λ° μλ° 5μμ StringBuffer, StringBuilder, String, CharBuffer λ±μ λΉμ·ν λΆλ₯μ νμ μ μν κ³΅ν΅ μΈν°νμ΄μ€λ‘ CharSequenceκ° λ±μ₯νμκ³ , μμ°μ€λ½κ² Stringμλ CharSequenceλ₯Ό λ°μ contentEqualsκ° λ€μ€μ μλμλ€.
κ·Έ κ²°κ³Ό μ΄λ² μμ΄ν μ μ§μΉ¨μ λλκ³ μ΄κΈ°λ λͺ¨μ΅μ΄ λμλ€. λ€νν μ΄ λ λ©μλλ κ°μ κ°μ²΄λ₯Ό μ λ ₯νλ©΄ μμ ν κ°μ μμ μ μνν΄μ£Όλ ν΄λ‘μΈ κ±΄ μ ν μλ€.
μ΄λ€ λ€μ€μ μ λ©μλκ° λΆλ¦¬λμ§ λͺ°λΌλ κΈ°λ₯μ΄ λκ°λ€λ©΄ μλμ κ°μ λ°©λ²μ μ¬μ©ν΄ μμ νκ² λ©μλλ₯Ό μ μν μ μλ€.
μλμ μΌλ‘ λ νΉμν λ€μ€μ μ λ©μλμμ λ νΉμν (λ μΌλ°μ μΈ) λ€μ€μ μ λ©μλλ‘ μΌμ λ겨λ²λ¦¬λ κ²μ΄λ€.
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence) sb);
}