item 30 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

이왕이면 μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ§Œλ“€λΌ

  • ν΄λž˜μŠ€μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ λ©”μ„œλ“œλ„ μ œλ„€λ¦­μœΌλ‘œ λ§Œλ“€ 수 μžˆλ‹€.

  • λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ„ λ°›λŠ” 정적 μœ ν‹Έλ¦¬ν‹° λ©”μ„œλ“œλŠ” 보톡 μ œλ„€λ¦­μ΄λ‹€.

https://stackoverrun.com/ko/q/12305035

  • Collections의 μ•Œκ³ λ¦¬μ¦˜ λ©”μ„œλ“œ(binarySearch, sort λ“±)λŠ” λͺ¨λ‘ μ œλ„€λ¦­μ΄λ‹€.
  • 둜 νƒ€μž… μ‚¬μš© - μ•ˆν‹°νŒ¨ν„΄
public static Set union(Set s1, Set s2) {
	Set result = new HashSet(s1);
    result.addAll(s2);
    return result;
}

μ»΄νŒŒμΌμ€ λ˜μ§€λ§Œ κ²½κ³ κ°€ λ°œμƒν•œλ‹€.

κ²½κ³ λ₯Ό μ—†μ• κΈ° μœ„ν•΄μ„œλŠ” 이 λ©”μ„œλ“œλ₯Ό type safeν•˜κ²Œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. μ œλ„€λ¦­μ„ 톡해 type safeν•˜κ²Œλ§Œλ“€μ–΄ 보자

// μ»΄νŒŒμΌμ€ λ˜μ§€λ§Œ κ²½κ³ κ°€ λ‘κ°œ λ°œμƒν•œλ‹€. 
Union.java:5: warning: [unchecked] unchecked call to HashSet(Collection<? extends E> as a member of raw type HashSet
Set result = new HashSet(s1);
              *μ—λŸ¬λ°œμƒ*

Union.java:6: warning: [unchecked] unchecked call to addAll(Collection<? extends E> as a member of raw type Set
result.addAll(s2);

κ²½κ³ λ₯Ό μ—†μ• λ €λ©΄ 이 λ©”μ„œλ“œλ₯Ό νƒ€μž… μ•ˆμ „ν•˜κ²Œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. λ©”μ„œλ“œ μ„ μ–Έμ—μ„œμ˜ μ„Έ 집합(μž…λ ₯ 2개, λ°˜ν™˜ 1개)의 μ›μ†Œ νƒ€μž…μ„ νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ λͺ…μ‹œ

λ©”μ„œλ“œ μ•ˆμ—μ„œλ„ 이 νƒ€μž… λ§€κ°œλ³€μˆ˜λ§Œ μ‚¬μš©ν•˜κ²Œ μˆ˜μ •ν•˜λ©΄ λœλ‹€. (νƒ€μž… λ§€κ°œλ³€μˆ˜λ“€μ„ μ„ μ–Έν•˜λŠ”) νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ€ λ©”μ„œλ“œμ˜ μ œν•œμžμ™€ λ°˜ν™˜ νƒ€μž… 사이에 μ˜¨λ‹€.

  • λ‹€μŒ μ½”λ“œμ—μ„œ νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ€ λ©”μ„œλ“œμ˜ μ œν•œμžμ™€ λ°˜ν™˜ νƒ€μž… 사이에 μ˜¨λ‹€.
  • λ‹€μŒ μ½”λ“œμ—μ„œ νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ€ 이고 λ°˜ν™˜ νƒ€μž…μ€ Set이닀.
  • νƒ€μž… 맀개 λ³€μˆ˜μ˜ λͺ…λͺ… κ·œμΉ™μ€ μ œλ„€λ¦­ λ©”μ„œλ“œλ‚˜ μ œλ„€λ¦­ νƒ€μž…μ΄λ‚˜ λ˜‘κ°™λ‹€. (μ•„μ΄ν…œ 29, 68)
// μ œλ„€λ¦­ λ©”μ„œλ“œ 
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
    Set<E> result = new HashSet<>(s1);
    result.addAll(s2);
    return result;
}
  • λ‹¨μˆœν•œ μ œλ„€λ¦­ λ©”μ„œλ“œλΌλ©΄ μΆ©λΆ„ν•˜λ‹€
  • 이 λ©”μ„œλ“œλŠ” κ²½κ³  없이 컴파일되며 νƒ€μž… μ•ˆμ „ν•˜κ³  쓰기도 쉽닀.

μ œλ„€λ¦­ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜λŠ” κ°„λ‹¨ν•œ ν”„λ‘œκ·Έλž¨

public static void main(String[] args) {
   Set<String> guys = Set.of("ν†°", "λ”•", "혜리");
   Set<String> guys = Set.of("래리", "λͺ¨μ—", "컬리");
   Set<String> aflCio = union(guys, stooges);
   System.out.println(aflCio);

}
  • 이 ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ©΄ "[λͺ¨μ—, ν†°, 해리, 래리, 컬리, λ”•]" 이 좜λ ₯λœλ‹€. (μ›μ†Œ μˆœμ„œλŠ” κ΅¬ν˜„ 방식에 λ”°λΌμ„œ 달라진닀.)
  • union λ©”μ„œλ“œλŠ” 집합 3개 (μž…λ ₯ 2개, λ°˜ν™˜ 1개)의 νƒ€μž…μ΄ λͺ¨λ‘ κ°™μ•„μ•Ό ν•œλ‹€. 이λ₯Ό ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…(μ•„μ΄ν…œ 31)을 μ‚¬μš©ν•˜μ—¬ 더 μœ μ—°ν•˜κ²Œ κ°œμ„ ν•  수 μžˆλ‹€.
  • λ•Œλ•Œλ‘œ λΆˆλ³€ 객체λ₯Ό μ—¬λŸ¬ νƒ€μž…μœΌλ‘œ ν™œμš©ν•  수 있게 λ§Œλ“€μ–΄μ•Ό ν•  λ•Œκ°€ μžˆλ‹€.
  • μ œλ„€λ¦­μ€ λŸ°νƒ€μž„μ— νƒ€μž… 정보가 μ†Œκ±°(μ•„μ΄ν…œ 28)λ˜λ―€λ‘œ ν•˜λ‚˜μ˜ 객체λ₯Ό μ–΄λ–€ νƒ€μž…μœΌλ‘œλ“  λ§€κ°œλ³€μˆ˜ν™”ν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ ν•˜λ €λ©΄ μš”μ²­ν•œ νƒ€μž… 맀개 λ³€μˆ˜μ— 맞게 맀번 κ·Έ 객체의 νƒ€μž…μ„ λ°”κΏ”μ£ΌλŠ” 정적 νŒ©ν„°λ¦¬λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

  • 이 νŒ¨ν„΄μ„ μ œλ„€λ¦­ μ‹±κΈ€ν„΄ νŒ©ν„°λ¦¬λΌ ν•˜λ©° Collections.reverseOrder 같은 ν•¨μˆ˜ 객체(μ•„μ΄ν…œ 42)λ‚˜ Collections.emptySet 같은 μ»¬λ ‰μ…˜μš©μœΌλ‘œ μ‚¬μš©ν•œλ‹€.

ν•­λ“± ν•¨μˆ˜λ₯Ό 담은 클래슀λ₯Ό λ§Œλ“€μž.

  • μžλ°” 라이브러리의 Function.identityλ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.(μ•„μ΄ν…œ 59)
  • ν•­λ“±ν•¨μˆ˜ κ°μ²΄λŠ” μƒνƒœκ°€ μ—†μœΌλ‹ˆ μš”μ²­ν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œ μƒμ„±ν•˜λŠ” 것은 λ‚­λΉ„λ‹€.
  • μžλ°”μ˜ μ œλ„€λ¦­μ΄ μ‹€μ²΄ν™”λœλ‹€λ©΄ ν•­λ“±ν•¨μˆ˜λ₯Ό νƒ€μž…λ³„λ‘œ ν•˜λ‚˜μ”© λ§Œλ“€μ–΄μ•Ό ν–ˆκ² μ§€λ§Œ μ†Œκ±° 방식을 μ‚¬μš©ν•œ 덕에 μ œλ„€λ¦­ μ‹±κΈ€ν„΄ ν•˜λ‚˜λ©΄ μΆ©λΆ„ν•˜λ‹€.
private static UnaryOperator<Object> IDENTITY_FN = (t) -> t;

@SuppressWarnings("unchecked")
public static <T> UnaryOPerator<T> identityFunction() {
    return (UnaryOperator<T>) INDENTITY_FN;
}
  • INDENTITY_FN을 UnaryOperator둜 ν˜•λ³€ν™˜ν•˜λ©΄ 비검사 ν˜•λ³€ν™˜ κ²½κ³ κ°€ λ°œμƒν•œλ‹€.
  • Tκ°€ μ–΄λ–€ νƒ€μž…μ΄λ“  UnaryOperatorλŠ” UnaryOperatorκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ΄λ‹€.
  • ν•­λ“±ν•¨μˆ˜λž€ μž…λ ₯값을 μˆ˜μ • 없이 κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜λŠ” νŠΉλ³„ν•œ ν•¨μˆ˜μ΄λ―€λ‘œ Tκ°€ μ–΄λ–€ νƒ€μž…μ΄λ“  UnaryOperatorλ₯Ό μ‚¬μš©ν•΄λ„ νƒ€μž… μ•ˆμ „ν•˜λ‹€.

μž¬κ·€μ  νƒ€μž… ν•œμ •

  • 주둜 νƒ€μž…μ˜ μžμ—°μ  μˆœμ„œλ₯Ό μ •ν•˜λŠ” Comparable μΈν„°νŽ˜μ΄μŠ€(μ•„μ΄ν…œ 14)와 ν•¨κ»˜ 씅쓰인닀.
public interface Comparable<T> {
   int compareTo(T o);
} 
  • μ—¬κΈ°μ„œ νƒ€μž… λ§€κ°œλ³€μˆ˜ TλŠ” Comparableλ₯Ό κ΅¬ν˜„ν•œ νƒ€μž…μ΄ 비ꡐ할 수 μžˆλŠ” μ›μ†Œμ˜ νƒ€μž…μ„ μ •μ˜ν•œλ‹€.
  • μ‹€μ œλ‘œ 거의 λͺ¨λ“  νƒ€μž…μ€ μžμ‹ κ³Ό 같은 νƒ€μž…μ˜ μ›μ†Œμ™€λ§Œ 비ꡐ할 수 μžˆλ‹€.
  • λ”°λΌμ„œ String은 Comparable을 κ΅¬ν˜„ν•˜κ³  IntegerλŠ” Comparableλ₯Ό κ΅¬ν˜„ν•˜λŠ” 식이닀.

Comparable을 κ΅¬ν˜„ν•œ μ›μ†Œμ˜ μ»¬λ ‰μ…˜μ„ μž…λ ₯λ°›λŠ” λ©”μ„œλ“œλ“€μ€ 주둜 κ·Έ μ›μ†Œλ“€μ„ μ •λ ¬ ν˜Ήμ€ κ²€μƒ‰ν•˜κ±°λ‚˜ μ΅œμ†Ÿκ°’μ΄λ‚˜ μ΅œλŒ“κ°’μ„ κ΅¬ν•˜λŠ” μ‹μœΌλ‘œ μ‚¬μš©λœλ‹€.

이 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ €λ©΄ μ»¬λ ‰μ…˜μ— λ‹΄κΈ΄ λͺ¨λ“  μ›μ†Œκ°€ μƒν˜Έ 비ꡐ될 수 μžˆμ–΄μ•Ό ν•œλ‹€.

νƒ€μž… ν•œμ •μΈ <E extends Comparable>λŠ” "λͺ¨λ“  νƒ€μž… EλŠ” μžμ‹ κ³Ό 비ꡐ할 수 μžˆλ‹€"라고 읽을 수 μžˆλ‹€.

μƒν˜Έ 비ꡐ κ°€λŠ₯ν•˜λ‹€λŠ” λœ»μ„ μ•„μ£Ό μ •ν™•ν•˜κ²Œ ν‘œν˜„ν–ˆλ‹€κ³  ν•  수 μžˆλ‹€.

// μ»¬λ ‰μ…˜μ— λ‹΄κΈ΄ μ›μ†Œμ˜ μžμ—°μ  μˆœμ„œλ₯Ό κΈ°μ€€μœΌλ‘œ μ΅œλŒ“κ°’μ„ κ³„μ‚°ν•˜λ©° 컴파일 였λ₯˜λ‚˜ κ²½κ³ λŠ” λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. 
public static <E extends Comparable<E>> E max(Collection<E> c) {
   if(c.isEmpty()) 
        throw new IllegalArgumentException("μ»¬λ ‰μ…˜μ΄ λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€.");
   E result = null;
   for (E e : c) 
       if (result == null || e.compareTo(result) > 0) 
           result = Objects.requireNonNull(e);
       return result;

}

이 λ©”μ„œλ“œμ— 빈 μ»¬λ ‰μ…˜μ„ 건내면 IllegalArgumentException을 λ˜μ§€λ‹ˆ Optionalλ₯Ό λ°˜ν™˜ν•˜λ„λ‘ κ³ μΉ˜λŠ” 편이 λ‚˜μ„ 것이닀. (μ•„μ΄ν…œ 55)

핡심 정리

  • μ œλ„€λ¦­ νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μž…λ ₯ λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ„ λͺ…μ‹œμ μœΌλ‘œ ν˜•λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” λ©”μ„œλ“œλ³΄λ‹€ μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ 더 μ•ˆμ „ν•˜λ©° μ‚¬μš©ν•˜κΈ°λ„ 쉽닀.
  • νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ λ©”μ„œλ“œλ„ ν˜•λ³€ν™˜ 없이 μ‚¬μš©ν•  수 μžˆλŠ” 편이 μ’‹μœΌλ©° λ§Žμ€ 경우 κ·Έλ ‡κ²Œ ν•˜λ €λ©΄ μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ λ˜μ–΄μ•Ό ν•œλ‹€.
  • ν˜•λ³€ν™˜ ν•΄μ€˜μ•Ό ν•˜λŠ” κΈ°μ‘΄ λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ν•˜κ²Œ λ§Œλ“€μž. (μ•„μ΄ν…œ 26 둜 νƒ€μž…μ€ μ‚¬μš©ν•˜μ§€ 말라.)
⚠️ **GitHub.com Fallback** ⚠️