πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”

λ‹€μ€‘μ •μ˜λŠ” μ‹ μ€‘νžˆ μ‚¬μš©ν•˜λΌ - [8μž₯. λ©”μ„œλ“œ(μ•„μ΄ν…œ52)]

Amenable 2023. 12. 11. 17:29

πŸ“™ 1. λ‹€μ€‘μ •μ˜μ˜ 문제

  μ»¬λ ‰μ…˜μ„ 'μ§‘ν•©, 리슀트, κ·Έ μ™Έ'둜 κ΅¬λΆ„ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ΄ μžˆλ‹€κ³  ν•˜μž.

public class CollectionClassifier {
    public static String classify(Set<?> s) {
        return "μ§‘ν•©";
    }

    public static String classify(List<?> s) {
        return "μ§‘ν•©";
    }

    public static String classify(Collection<?> s) {
        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));
        }
    }
}

  "μ§‘ν•©", "리슀트", "κ·Έ μ™Έ"λ₯Ό μ°¨λ‘€λŒ€λ‘œ 좜λ ₯ν• κΉŒ?

  μ•„λ‹ˆλ‹€. "κ·Έ μ™Έ", "κ·Έ μ™Έ", "κ·Έ μ™Έ"λ₯Ό 좜λ ₯ν•œλ‹€.

  κ·Έ μ΄μœ λŠ” λ‹€μ€‘μ •μ˜(overloading, μ˜€λ²„λ‘œλ”©)된 λ©”μ„œλ“œλ“€ 쀑 μ–΄λŠ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€κ°€ μ»΄νŒŒμΌνƒ€μž„μ— μ •ν•΄μ§€κΈ° λ•Œλ¬Έμ΄λ‹€. 'HashSet, ArrayList, HashMap'νƒ€μž…μœΌλ‘œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 게 μ•„λ‹ˆλΌ for문에 μžˆλŠ” 'Collection'νƒ€μž…μœΌλ‘œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€. 즉, νƒ€μž…이 λ§€λ²ˆ λ‹¬λΌμ§€λŠ” λŸ°νƒ€μž„ κΈ°μ€€μœΌλ‘œ ν˜ΈμΆœν•˜λŠ” κ²ƒμ΄ μ•„λ‹Œ μ»΄νŒŒμΌνƒ€μž„ κΈ°μ€€μœΌλ‘œ ν˜ΈμΆœν•œλ‹€λŠ” κ²ƒμ΄λ‹€.

 

  ν•΄λ‹Ή λ‚΄μš©μ΄ μ΅μˆ™ν•˜μ§€ μ•Šμ€ μ΄μœ λŠ” μž¬μ •μ˜(overriding, μ˜€λ²„λΌμ΄λ”©) λ•Œλ¬Έμ΄λ‹€.

class Wine {
    String name() {
        return "포도주";
    }
}

class SparklingWine extends Wine {
    @Override
    String name() {
        return "λ°œν¬μ„± 포도주";
    }
}

class Champagne extends Wine {
    @Override
    String name() {
        return "μƒ΄νŽ˜μΈ";
    }
}


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());
    }
}

  이 ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” "포도주", "λ°œν¬μ„± 포도주", "μƒ΄νŽ˜μΈ"이 좜λ ₯λœλ‹€.

  κ·Έ μ΄μœ λŠ” μž¬μ •μ˜ν•œ λ©”μ„œλ“œ(μ˜€λ²„λΌμ΄λ”©)λŠ” λ™μ μœΌλ‘œ μ„ νƒλ˜κ³ , λ‹€μ€‘μ •μ˜ν•œ λ©”μ„œλ“œ(μ˜€λ²„λ‘œλ”©)λŠ” μ •μ μœΌλ‘œ μ„ νƒλ˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

  μ»¬λ ‰μ…˜μ„ λΆ„λ₯˜ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ€ λ‹€μŒκ³Ό 같은 λ°©λ²•μœΌλ‘œ μš°λ¦¬κ°€ μ›ν•˜λŠ” λ™μž‘μ„ μˆ˜ν–‰ν•˜κ²Œ ν•  수 μžˆλ‹€.

public static String classify(Collection<?> c) {
    return c instanceof Set ? "μ§‘ν•©" :
           c instanceof List ? "리슀트" " "κ·Έ μ™Έ";
}

 

πŸ“™ 2. λ‹€μ€‘μ •μ˜μ˜ 문제 μ˜ˆμ‹œ

  λ‹€μ€‘μ •μ˜ 문제의 μ˜ˆμ‹œλ“€μ„ 쑰금 더 μ‚΄νŽ΄λ³΄μž.

πŸ“Œ 1. μ œλ„€λ¦­κ³Ό μ˜€ν† λ°•μ‹±μ— λ”°λ₯Έ 문제

  μžλ°” 언어에 μ œλ„€λ¦­κ³Ό μ˜€ν† λ°•μ‹±μ„ λ”ν•œ κ²°κ³Ό List μΈν„°νŽ˜μ΄μŠ€κ°€ μ·¨μ•½ν•΄μ‘Œλ‹€.

public static void main(String[] args) {
    Set<Integer> set = new TreeSet<>();
    List<Integer> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();

    for(int i = -3; i < 3; i++) {
        set.add(i);
        list1.add(i);
        list2.add(i);
    }

    for(int i = 0; i < 3; i++) {
        set.remove(i);
        list1.remove(i);
        list2.remove((Integer) i);
    }

    System.out.println(set);
    // [-3, -2, -1]
    System.out.println(list1);
    // [-2, 0, 2]
    System.out.println(list2);
    // [-3, -2, -1]
}

  list2κ°€ μ—†λ‹€κ³  μƒκ°ν•˜λ©΄ list1μ—μ„œλ„ setκ³Ό λ™μΌν•˜κ²Œ κ°’ "0", "1", "2"λ₯Ό μ œκ±°ν•˜μ—¬ "[-3, -2, -1]"을 얻을 거라고 μƒκ°ν–ˆμ„ 것이닀. ν•˜μ§€λ§Œ, list1의 경우 remove(Object)κ°€ μ•„λ‹Œ remove(int index)둜 λ‹€μ€‘μ •μ˜λœ λ©”μ„œλ“œλ₯Ό μ„ νƒν•˜μ—¬ μ°¨λ‘€λ‘œ 0번째, 1번째, 2번째 μ›μ†Œλ₯Ό μ œκ±°ν•˜μ—¬ "[-2, 0, 2]"κ°€ λ‚¨κ²Œ λ˜λŠ” 것이닀. μ˜ˆμƒν•œ λŒ€λ‘œ μ‚¬μš©ν•˜λ €λ©΄ list2처럼 'list2.remove((Integer) i)'λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

πŸ“Œ 2. λžŒλ‹€μ™€ λ©”μ„œλ“œ 참쑰에 λ”°λ₯Έ 문제

  μžλ°” 8μ—μ„œ λ„μž…ν•œ λžŒλ‹€μ™€ λ©”μ„œλ“œ μ°Έμ‘° μ—­μ‹œ λ‹€μ€‘μ •μ˜ μ‹œμ˜ ν˜Όλž€μ„ ν‚€μ› λ‹€.

// 1번. Thread의 μƒμ„±μž 호좜
new Thread(System.out::println).start();

// 2번. ExecutorService의 submit λ©”μ„œλ“œ 호좜
ExecutorService exec = Executors.newCachedThreadPool();
exec.submit(System.out::println);

  1번과 2번이 λΉ„μŠ·ν•΄ λ³΄μ΄μ§€λ§Œ, 2λ²ˆμ—μ„œ 컴파일 였λ₯˜κ°€ λ‚œλ‹€. κ·Έ μ΄μœ λŠ” submit 닀쀑 μ •μ˜ λ©”μ„œλ“œ μ€‘μ—λŠ” Callable<T>λ₯Ό λ°›λŠ” λ©”μ„œλ“œκ°€ 있기 λ•Œλ¬Έμ΄λ‹€.

  2번의 경우 1번과 같이 Runnable을 λ°›μœΌλ €κ³  ν•˜μ˜€λŠ”λ° Callable<T>을 λ°›λŠ” λ©”μ„œλ“œλ„ 같이 μžˆλŠ” κ²½μš°λ‹€. 'System.out::println'은 voidλ₯Ό λ°˜ν™˜ν•˜λŠ”λ° Callable의 κ²½μš°λŠ” λ°˜ν™˜κ°’이 μžˆμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— μ»΄νŒŒμΌ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” κ²ƒμ΄λ‹€.

 

πŸ“™ 3. λ‹€μ€‘μ •μ˜ 문제의 ν•΄κ²°μ±…

  μ§€κΈˆκΉŒμ§€ μ‚΄νŽ΄λ³Έ κ²ƒμ²˜λŸΌ λ‹€μ€‘μ •μ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ—¬λŸ¬ κ°€μ§€ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•œ ν•΄κ²°μ±…듀을 μ‚΄νŽ΄λ³΄μž.

πŸ“Œ 1. λ‹€μ€‘μ •μ˜κ°€ ν˜Όλˆμ„ μΌμœΌν‚€λŠ” 상황을 ν”Όν•˜μž.

  μ•ˆμ „ν•˜κ³  보수적으둜 κ°€λ €λ©΄ λ§€κ°œλ³€μˆ˜ μˆ˜κ°€ 같은 λ‹€μ€‘μ •μ˜λŠ” λ§Œλ“€μ§€ 말아야 ν•œλ‹€.

πŸ“Œ 2. κ°€λ³€μΈμˆ˜(varargs)λ₯Ό μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œλΌλ©΄ λ‹€μ€‘μ •μ˜λ₯Ό μ•„μ˜ˆ ν•˜μ§€ 말아야 ν•œλ‹€.

πŸ“Œ 3. λ‹€μ€‘μ •μ˜ν•˜λŠ” λŒ€μ‹  λ©”μ„œλ“œ 이름을 λ‹€λ₯΄κ²Œ μ§“μž.

  java.io.ObjectOutputStream 클래슀처럼 λ‹€μ€‘μ •μ˜ν•˜λŠ” λŒ€μ‹  λ©”μ„œλ“œ 이름을 λ‹€λ₯΄κ²Œ 지어쀄 수 μžˆλ‹€.

  • writeBoolean(boolena)
  • writeInt(int)
  • writeLong(long)
  • readBoolean()
  • readInt()
  • readLong()

πŸ“Œ 4. 정적 νŒ©ν„°λ¦¬λ₯Ό ν™œμš©ν•˜μž.

  μƒμ„±μžμ˜ 경우 이름을 λ‹€λ₯΄κ²Œ 지을 수 μ—†λ‹€. μ΄λŸ¬ν•œ κ²½μš°μ—λŠ” 정적 νŒ©ν„°λ¦¬λ₯Ό μ΄μš©ν•  수 μžˆλ‹€.

 

ν•΄λ‹Ή 글은 Joshua Bloch λ‹˜μ˜ 'Effective Java 3/E'λ₯Ό μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.