[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item30. 이왕이면 μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ§Œλ“€λΌ.

2023. 3. 21. 09:39ㆍJAVA/Effective JAVA

728x90

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item30. 이왕이면 μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ§Œλ“€λΌ. 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item29. 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ. (tistory.com)

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item29. 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ.

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item29. 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIA

hyejin.tistory.com

ν΄λž˜μŠ€μ™€ 같이 λ©”μ„œλ“œλ„ μ œλ„€λ¦­μœΌλ‘œ λ§Œλ“€ 수 μžˆλŠ”λ°, λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ„ λ°›λŠ” 정적 μœ ν‹Έλ¦¬ν‹° λ©”μ„œλ“œλŠ” 보톡 μ œλ„€λ¦­μ΄λ‹€. 

ex) Collections의 binarySearch, sort λ“±μ˜ λ©”μ„œλ“œλŠ” λͺ¨λ‘ μ œλ„€λ¦­μ΄λ‹€. 

 

 

 

public class Union
{
   // μ œλ„€λ¦­ μ‚¬μš© μ „ λ©”μ„œλ“œ
   public static Set union(Set s1, Set s2)
   {
      Set result = new HashSet(s1);
      result.addAll(s2);
      return result;
   }
   
   public static void main(String[] args)
   {
      Set guys = Set.of("ν†°", "λ‹₯", "해리");
      Set stooges = Set.of(1, 2, 3);
      Set all = union(guys, stooges);
      
      for (Object o : all)
      {
         System.out.println("o = " + (String) o);
      }
   }
}

 

λ‹€μŒ union λ©”μ„œλ“œλŠ” 두 μ§‘ν•©μ˜ 합집합을 λ°˜ν™˜ν•˜λŠ”λ° μ΄λ•Œ λ¬Έμ œκ°€ μžˆλŠ” λ©”μ„œλ“œμ΄λ‹€. 

컴파일 μ—λŸ¬λŠ” μ—†μ§€λ§Œ 이λ₯Ό 싀행해보면 λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” 것을 확인할 수 μžˆλ‹€. 

 

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

public class Union
{
   // μ œλ„€λ¦­ λ©”μ„œλ“œ
   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> stooges = Set.of("래리", "λͺ¨μ—", "컬리");
//    Set<Integer> stooges = Set.of(1, 2, 3);
      Set<String> all = union(guys, stooges); // <Integer> λŠ” 같은 νƒ€μž…μ„ λ„£μœΌλΌκ³  ν–ˆκΈ° λ•Œλ¬Έμ— error
      
      for (String o : all)
      {
         System.out.println("o = " + o);
      }
   }
}

νƒ€μž… λ§€κ°œλ³€μˆ˜λ“€μ„ μ„ μ–Έν•˜λŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ€ λ©”μ„œλ“œμ˜ μ œν•œμžμ™€ λ°˜ν™˜ νƒ€μž… 사이에 μ˜¨λ‹€. 

μ œλ„€λ¦­ λ©”μ„œλ“œλŠ” κ²½κ³  없이 이제 컴파일 되고, νƒ€μž… μ•ˆμ „ν•˜λ©°, 쓰기도 μ‰½λ‹€λŠ” μž₯점이 μžˆλ‹€. 

union λ©”μ„œλ“œλŠ” μ§‘ν•© 3개(μž…λ ₯ 2개, λ°˜ν™˜ 1개)의 νƒ€μž…μ΄ λͺ¨λ‘ κ°™μ•„μ•Ό ν•œλ‹€. (μ΄λŠ” ν•œμ •μ  μ™€μΌλ“œ μΉ΄λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ’€ 더 μœ μ—°ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.)

 

 

μ œλ„€λ¦­ μ‹±κΈ€ν„΄ νŒ©ν„°λ¦¬ 

λ•Œλ•Œλ‘œ λΆˆλ³€ 객체λ₯Ό μ—¬λŸ¬ νƒ€μž…μœΌλ‘œ ν™œμš©ν•  수 있게 λ§Œλ“€μ–΄μ•Ό ν•  λ•Œκ°€ μžˆλ‹€. 

μ œλ„€λ¦­μ€ λŸ°νƒ€μž„μ— νƒ€μž… 정보가 μ†Œκ±°λ˜λ―€λ‘œ ν•˜λ‚˜μ˜ 객체λ₯Ό μ–΄λ–€ νƒ€μž…μœΌλ‘œλ“  λ§€κ°œλ³€μˆ˜ν™”ν•  수 μžˆλ‹€. 

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

μ΄λŸ¬ν•œ νŒ¨ν„΄μ„ μ œλ„€λ¦­ μ‹±κΈ€ν„΄ νŒ©ν„°λ¦¬λΌκ³  ν•œλ‹€. 

 

public class GenericSingletonFactory
{
   public static Function<String, String> stringIndentityFunction()
   {
      return (t) -> t;
   }
   
   public static Function<Number, Number> integerIdentityFunction()
   {
      return (t) -> t;
   }
   
   
   public static void main(String[] args)
   {
      String[] strings = { "μ‚Όλ² ", "λŒ€λ§ˆ", "λ‚˜μΌλ‘ " };
      Function<String, String> sameString = stringIndentityFunction();
      for (String string : strings)
      {
         System.out.println("sameString = " + sameString.apply(string));
      }
      
      Number[] numbers = { 1, 2.0, 3L };
      Function<Number, Number> sameNumber = integerIdentityFunction();
      for (Number number : numbers)
      {
         System.out.println("sameNumber = " + sameNumber.apply(number));
      }
   }
}

-> 이 ν΄λž˜μŠ€λŠ” ν•­λ“±ν•¨μˆ˜λ₯Ό 담은 클래슀둜 μ§€κΈˆμ€ μ œλ„€λ¦­ μ‚¬μš©ν•˜κΈ° μ „μœΌλ‘œ ν•­λ“±ν•¨μˆ˜λ₯Ό νƒ€μž…λ³„λ‘œ ν•˜λ‚˜μ”© λ§Œλ“€μ–΄μ•Ό ν–ˆμ§€λ§Œ, 

 

public class GenericSingletonFactory
{
   // μ œλ„€λ¦­ 싱글톀 νŒ©ν„°λ¦¬ νŒ¨ν„΄
   private static UnaryOperator<Object> IDENTITY_FN = (t) -> t;
   
   @SuppressWarnings("unchecked")
   public static <T> UnaryOperator<T> identityFunction()
   {
      return (UnaryOperator<T>) IDENTITY_FN;
   }
   
   public static void main(String[] args)
   {
      String[] strings = { "μ‚Όλ² ", "λŒ€λ§ˆ", "λ‚˜μΌλ‘ " };
      UnaryOperator<String> sameString = identityFunction();
      for (String string : strings)
      {
         System.out.println("sameString = " + sameString.apply(string));
      }
      
      Number[] numbers = { 1, 2.0, 3L };
      UnaryOperator<Number> sameNumber = identityFunction();
      for (Number number : numbers)
      {
         System.out.println("sameNumber = " + sameNumber.apply(number));
      }
   }
}

μ†Œκ±° 방식을 μ‚¬μš©ν•œ 덕에 μ œλ„€λ¦­ μ‹±κΈ€ν„΄ ν•˜λ‚˜λ§Œ μΆ©λΆ„νžˆ μ‚¬μš©ν•  수 μžˆλ‹€. 

public static <T> UnaryOperator<T> identityFunction()
{
   return (UnaryOperator<T>) IDENTITY_FN;
}

μ—¬κΈ°μ„œ IDENDITY_FN을 UnaryOperator<T>둜 ν˜•λ³€ν™˜ν•˜λ©΄ 비검사 ν˜•λ³€ν™˜ κ²½κ³ κ°€ λ°œμƒν•œλ‹€. 

Tκ°€ μ–΄λ–€ νƒ€μž…μ΄λ“  UnaryOpeartor<Object>λŠ” UnaryOperator<T>κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ΄λ‹€. 

 

그런데 μœ„μ˜ μ˜ˆμ œλŠ” ν•­λ“±ν•¨μˆ˜λ‘œ μž…λ ₯ 값을 μˆ˜μ •μ—†μ΄ κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜κ³  있기 λ•Œλ¬Έμ— Tκ°€ μ–΄λ–€ νƒ€μž…μ΄λ“  UnaryOperator<T>λ₯Ό μ‚¬μš©ν•΄λ„ νƒ€μž… μ•ˆμ „ν•˜λ‹€. 

λ”°λΌμ„œ @SuppressWarning μ–΄λ…Έν…Œμ΄μ…˜μ„ μΆ”κ°€ν•΄μ„œ κ²½κ³ λ₯Ό 숨길 수 μžˆλ‹€. 

 

 

 

 

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

: 자기 μžμ‹ μ΄ λ“€μ–΄κ°„ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜μ—¬ νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ ν—ˆμš© λ²”μœ„λ₯Ό ν•œμ •ν•  수 μžˆλ‹€. 

public class RecursiveTypeBound
{
   // μž¬κ·€μ  νƒ€μž… ν•œμ •μ„ μ‚¬μš©ν•΄ μ»¬λ ‰μ…˜μ—μ„œ μ΅œλŒ€κ°’μ„ λ°˜ν™˜ν•œλ‹€.
   public static <E extends Comparable<E>> E max(Collection<E> collection)
   {
      if (collection.isEmpty()) {
         throw new IllegalArgumentException();
      }
      
      E result = null;
      for (E e : collection)
      {
         if (result == null || e.compareTo(result) > 0)
         {
            result = Objects.requireNonNull(e);
         }
      }
      
      return result;
   }
   
   public static void main(String[] args)
   {
      List<String> argList = List.of("hyejin", "park");
      System.out.println("max(argList) = " + max(argList));
   }
}

<E extends Comparable<E>> : λͺ¨λ“  νƒ€μž… EλŠ” μžμ‹ κ³Ό λΉ„κ΅ν• μˆ˜ μžˆλ‹€. 

 

 

 

 

πŸ“š 정리

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μž…λ ₯ λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ„ λͺ…μ‹œμ μœΌλ‘œ ν˜•λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” λ©”μ„œλ“œλ³΄λ‹€ μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ 더 μ•ˆμ „ν•˜λ©° μ‚¬μš©ν•˜κΈ° 쉽닀. 

λ©”μ„œλ“œλ„ νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ ν˜•λ³€ν™˜ 없이 μ‚¬μš©ν•  수 μžˆλŠ” 편이 μ’‹μœΌλ©°, κ·Έλ ‡κ²Œ ν•˜λ €λ©΄ 거의 μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ λ˜μ–΄μ•Ό ν•œλ‹€. 

λ”°λΌμ„œ νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ ν˜•λ³€ν™˜μ„ ν•΄μ€˜μ•Ό ν•˜λŠ” κΈ°μ‘΄ λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ν•˜κ²Œ λ§Œλ“€μž!!! 

 

 

 

 

 

 

 

 

 

 

728x90