Skip to content

Latest commit

Β 

History

History
220 lines (174 loc) Β· 6.43 KB

item29.md

File metadata and controls

220 lines (174 loc) Β· 6.43 KB

item 29. 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ.

  • μ œλ„€λ¦­μ΄ μ—†λŠ” Stack
public class Stack {
   private Object[] elements;
   private int size = 0;
   private static final int DEFAULT_INITIAL_CAPACITY = 16;

   public Stack() {
       elements = new Object[DEFAULT_INITIAL_CAPACITY];
   }

   public void push(Object e) {
       ensureCapacity();
       elements[size++] = e;
   }

   public Object pop() {
       if (size == 0) {
           throw new EmptyStackException();
       }

       Object result = elements[--size];
       elements[size] = null;
       return result;
   }
}
    @DisplayName("Object μŠ€νƒμ€ λ¬Έμ œκ°€ μžˆλ‹€!")
    @Test
    public void StackTest() {
        Stack stack = new Stack();

        stack.push(1);
        stack.push("1");

        assertEquals(stack.pop().getClass(), String.class);
        assertEquals(stack.pop().getClass(), String.class); // Integer !!
    }

- ν˜•λ³€ν™˜μ„ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ ν•΄μ€˜μ•Ό ν•œλ‹€ !

μ œλ„€λ¦­ νƒ€μž…μ˜ Stack 으둜 λ§Œλ“€κΈ°

  1. 클래슀 μ„ μ–Έ νƒ€μž… λ§€κ°œλ³€μˆ˜ μΆ”κ°€ν•˜κΈ°.
  2. Object λ₯Ό νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ λ°”κΎΈκΈ°.
public class GenericStack<E> {
    private E[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    
    public GenericStack() {
        elements = new E[DEFAULT_INITIAL_CAPACITY]; // μ—λŸ¬ λ°œμƒ!
        // 싀체화 λΆˆκ°€ νƒ€μž…μœΌλ‘œλŠ” 배열을 λ§Œλ“€ 수 μ—†μŒ.
    }

    public void push(E e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public E pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }

        E result = elements[--size];
        elements[size] = null;
        return result;
    }
}
  • μ œλ„€λ¦­μ€ 싀체화 λΆˆκ°€ νƒ€μž….
  • λŸ°νƒ€μž„ 정보가 μ»΄νŒŒμΌνƒ€μž„ 정보보닀 적닀.
  • λ°°μ—΄ 생성 λΆˆκ°€.

첫번째 방법 : Object λ°°μ—΄λ‘œ μƒμ„±ν•˜κ³  E λ°°μ—΄λ‘œ νƒ€μž… μΊμŠ€νŒ…

이미지

  • elements λŠ” private
  • E[] 둜 μ„ μ–Έλ˜μ–΄ push(E) 만 λ‹΄μ•„ νƒ€μž… μΊμŠ€νŒ…μ΄ μ•ˆμ „ !
  • @SuppressedWarning("unchecked") 뢙이기.

λ‘λ²ˆμ§Έ 방법 : κ·Έλƒ₯ Object λ°°μ—΄λ‘œ μ„ μ–Έν•˜κ³  μƒμ„±ν•˜κΈ°

이미지

  • push μ—μ„œ E νƒ€μž…λ§Œ 넣을 수 μžˆμœΌλ―€λ‘œ, elements λŠ” E 둜 무쑰건 νƒ€μž…λ³€ν™˜μ΄ κ°€λŠ₯.
  • @SuppressedWarning("unchecked") 뢙이기.

첫번째 λ°©λ²•μ˜ μž₯점

  • 첫번쨰 방법은 elements 배열을 μ“°λŠ” κ³³ μ—¬λŸ¬κ΅°λ°κ°€ μžˆλ”λΌλ„ νƒ€μž… μΊμŠ€νŒ…μ„ μƒμ„±μžμ—μ„œ ν•œλ²ˆλ§Œ 함.
  • (λ‘λ²ˆμ§Έ 방법은 맀번 νƒ€μž… μΊμŠ€νŒ…μ„ ν•΄μ€˜μ•Ό 함.)
  • 첫번쨰 방법이 가독성이 μ’‹μŒ.

첫번쨰 λ°©λ²•μ˜ 단점

  • νž™ μ˜€μ—Όμ΄ 생길 수 있음
  • λ§Œμ•½ Stack 의 push κ°€ μ•„λž˜μ™€ 같이 κ΅¬ν˜„λ˜μ—ˆλ‹€λ©΄ ?
    private E[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    @SuppressWarnings("unchecked")
    public GenericStack() {
        elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = (E) e;
    }
    public E pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }

        E result = elements[--size];
        elements[size] = null;
        return result;
    }
    public static void main(String[] args) {
        GenericStack<String> s = new GenericStack<>();
        
        s.push("Stack");
        s.push(1);
        
        s.pop();
        s.pop();
    }

νž™ μ˜€μ—Ό (Heap Pollution)

  • λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ΄ λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ΄ μ•„λ‹Œ 것을 μ°Έμ‘°ν•  λ–„ λ°œμƒν•˜λŠ” ν˜„μƒ.
  • λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ€ νƒ€μž… μ†Œκ±°κ°€ 이루어진닀.
  • λ”°λΌμ„œ λŸ°νƒ€μž„ μ‹œμ μ—λŠ” νƒ€μž… 정보λ₯Ό λͺ¨λ₯Έλ‹€.
  • ν•˜μ§€λ§Œ λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ΄ μ•„λ‹Œ 배열은 λŸ°νƒ€μž„ μ‹œμ μ— νƒ€μž… 정보λ₯Ό μ•ˆλ‹€.
  • λ”°λΌμ„œ μ»΄νŒŒμΌνƒ€μž„κ³Ό λŸ°νƒ€μž„μ˜ 정보가 λ‹¬λΌμ„œ, UncheckedWarning κ³Ό ClassCastException 이 λ°œμƒ.

νž™ μ˜€μ—Όμ΄ λ°œμƒν•˜λŠ” 경우

  1. raw νƒ€μž…κ³Ό λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ„ 같이 μ‚¬μš©ν•˜λŠ” 경우
List ln = new ArrayList<Number>();
List ls = new LinkedList<String>();
List<String> list;
list = ln; // unchecked warning + heap pollution
list = ls; // unchecked warning + NO heap pollution
  1. unchecked μΊμŠ€νŒ…μ„ ν•˜λŠ” 경우
List<? extends Number> ln = new ArrayList<Long>();
List<Short> ls = (List<Short>) ln; // unchecked warning + heap pollution
List<Long>  ll = (List<Long>)  ln; // unchecked warning + NO heap pollution

νƒ€μž… μ†Œκ±°

λ§€κ°œλ³€μˆ˜ν™” νƒ€μž… μ†Œκ±° ν›„
List<String> List
Map.Entry<String,Long> Map.Entry
Pair<Long,Long>[] Pair[]
Comparable<? super Number> Comparable
νƒ€μž… νŒŒλΌλ―Έν„° μ†Œκ±° ν›„
<T> Object
<T extends Number> Number
<T extends Comparable<T>> Comparable
<T extends Cloneable & Comparable<T>> Cloneable
<T extends Object & Comparable<T>> Object
<S, T extends S> Object,Object
λ§€κ°œλ³€μˆ˜ν™” λ©”μ„œλ“œ μ†Œκ±° ν›„
Iterator<E> iterator() Iterator iterator()
<T> T[] toArray(T[] a) Object[] toArray(Object[] a)
<U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) AtomicLongFieldUpdater newUpdater(Class tclass,String fieldName)

νž™ μ˜€μ—Ό

μ§„ν–‰ν•˜λ©΄μ„œ..

  • item 28 의 주제 (배열보닀 리슀트λ₯Ό μ‚¬μš©ν•˜λΌ) 와 달리 이번 μž₯μ—μ„œλŠ” 배열을 μ‚¬μš©ν–ˆλ‹€.
  • μ œλ„€λ¦­ νƒ€μž… μ•ˆμ—μ„œ 리슀트λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 항상 κ°€λŠ₯ν•˜μ§€λ„, 더 쒋은것도 μ•„λ‹ˆλ‹€.

κ²°λ‘ 

    public static void main(String[] args) {
        GenericStack<String> stack = new GenericStack<>();

        for (String s : List.of("hi", "hello", "bye")) {
            stack.push(s);
        }

        while (!stack.isEmpty()) {
            System.out.println(stack.pop().toUpperCase());
        }
    }
  • ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 영ν–₯을 주지 μ•ŠλŠ”λ‹€.
  • stack.pop() μ—μ„œ λͺ…μ‹œμ μΈ ν˜•λ³€ν™˜μ΄ ν•„μš” μ—†λ‹€.
  • μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€μž.