2023. 3. 20. 10:16γJAVA/Effective JAVA
[μ΄νν°λΈ μλ°] 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_INITIAL_CAPACITY];
}
public void push(Object e)
{
ensureCapacity();
}
public Object pop()
{
if (size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null;
return result;
}
public boolean isEmpty()
{
return size == 0;
}
private void ensureCapacity()
{
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
public static void main(String[] args)
{
Stack stack = new Stack();
for (String arg: List.of("a", "b", "c"))
{
stack.push(arg);
}
while (!stack.isEmpty())
{
System.out.println(((String) stack.pop()).toUpperCase());
}
}
}
μ΄ ν΄λμ€μμλ Object λ°°μ΄μ μ¬μ©ν΄μ Stackμ ꡬννλλ° μ§κΈ ν΄λμ€μμλ ν΄λΌμ΄μΈνΈ μ½λμμ κΊΌλΌ λ λ§λ€ κ°μ²΄λ₯Ό νλ³ν ν΄μΌ νλλ° μ΄λ λ°νμ μ€λ₯κ° λ μνμ΄ μλ€.
λ°λΌμ μ΄ ν΄λμ€λ μλ μ λ€λ¦ νμ μ΄μ΄μΌ νλ€.
1οΈβ£ E[] λ₯Ό μ΄μ©ν μ λ€λ¦ μ€ν
public class Stack<E>
{
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACTIY = 16;
// λ°°μ΄μ μ¬μ©ν μ½λλ₯Ό μ λ€λ¦μΌλ‘ λ§λλ λ°©λ² 1
// λ°°μ΄ elementsλ push(E) λ‘ λμ΄μ¨ E μΈμ€ν΄μ€λ§ λ΄λλ€.
// λ°λΌμ νμ
μμ μ±μ 보μ₯νμ§λ§,
// μ΄ λ°°μ΄μ λ°νμ νμ
μ E[]κ° μλ Object[] λ€!
// -> μ΄ λ°©λ²μ μ μΌν λ¨μ μ Heap μ€μΌμ΄ λ°μν μ μλ€λ μ μ΄λ€.
@SuppressWarnings("unchecked")
public Stack()
{
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACTIY];
}
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;
}
public boolean isEmpty()
{
return size == 0;
}
private void ensureCapacity()
{
if (elements.length == 0) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
public static void main(String[] args)
{
Stack<String> stack = new Stack<>();
for (String arg : List.of("a", "b", "c"))
{
stack.push(arg);
}
while (stack.isEmpty())
{
System.out.println(stack.pop().toUpperCase());
}
}
}
μΌλ° ν΄λμ€λ₯Ό μ λ€λ¦ ν΄λμ€λ‘ λ§λλ 첫λ²μ§Έ λ°©λ²μ ν΄λμ€ μ μΈμ νμ 맀κ°λ³μλ₯Ό μΆκ°νλ μΌμ΄λ€.
κ·Έλ¦¬κ³ μ΄λ νμ μ΄λ¦μΌλ‘λ λ³΄ν΅ Eλ₯Ό λ§μ΄ μ¬μ©νλ€.
@SuppressWarnings("unchecked")
public Stack()
{
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACTIY];
}
μ¬κΈ°μ 보면 Eμ κ°μ μ€μ²΄ν λΆκ° νμ μΌλ‘λ λ°°μ΄μ λ§λ€ μ μκΈ° λλ¬Έμ Object λ°°μ΄μ μμ±ν λ€μμ μ λ€λ¦ λ°°μ΄λ‘ νλ³νμ νλ λ°©λ²μ΄λ€. κ·Έλ¬κ³ λλ©΄ μ΄μ μ»΄νμΌ μ€λ₯κ° λ°μνμ§λ μμ§λ§ νμ μμ νμ§ μκΈ° λλ¬Έμ κ²½κ³ κ° λ¬λ€!
μ»΄νμΌλ¬ μ μ₯μμ 보면 μ΄ νλ‘κ·Έλ¨μ΄ νμ μμ νμ§ μ¦λͺ ν λ°©λ²μ΄ μμ§λ§ μ°λ¦¬λ μ μ μλ€.
elements λ°°μ΄μ private νλμ μ μ₯λκ³ , ν΄λΌμ΄μΈνΈλ‘ λ°νλκ±°λ λ€λ₯Έ λ©μλμ μ λ¬λλ μΌμ΄ μλ€.
κ·Έλ¦¬κ³ push λ©μλλ₯Ό ν΅ν΄ λ°°μ΄μ μ μ₯λλ μμμ νμ μ νμ Eμ΄λ€. λ°λΌμ μ΄ λΉκ²μ¬ νλ³νμ νμ€ν μμ νλ€!
μ΄λ κ² λΉκ²μ¬ νλ³νμ΄ μμ νλ€λΌλ κ²μ΄ μ¦λͺ λλ€λ©΄ λ²μλ₯Ό μ΅μλ‘ μ’νμ @SuppressWarnings("unchecked") μ΄λ Έν μ΄μ μ ν΅ν΄μ κ²½κ³ λ₯Ό μ¨κΈΈ μ μλ€.
2οΈβ£ Object[] λ₯Ό μ΄μ©ν μ λ€λ¦ Stack
public class Stack<E>
{
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACTIY = 16;
public Stack()
{
elements = new Object[DEFAULT_INITIAL_CAPACTIY];
}
public void push(E e)
{
ensureCapacity();
elements[size++] = e;
}
// λ°°μ΄μ μ¬μ©ν μ½λλ₯Ό μ λ€λ¦μΌλ‘ λ§λλ λ°©λ² 2
// λΉκ²μ¬ κ²½κ³ λ₯Ό μ μ ν μ¨κΈ΄λ€.
public E pop()
{
if (size == 0) {
throw new EmptyStackException();
}
// pushμμ E νμ
λ§ νμ©νλ―λ‘ μ΄ νλ³νμ μμ νλ€.
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null; // λ€ μ΄ μ°Έμ‘° ν΄μ
return result;
}
public boolean isEmpty()
{
return size == 0;
}
private void ensureCapacity()
{
if (elements.length == 0) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
public static void main(String[] args)
{
Stack<String> stack = new Stack<>();
for (String arg : List.of("a", "b", "c"))
{
stack.push(arg);
}
while (stack.isEmpty())
{
System.out.println(stack.pop().toUpperCase());
}
}
}
μ λ€λ¦ λ°°μ΄ μμ± μ€λ₯λ₯Ό ν΄κ²°νλ λλ²μ§Έ λ°©λ²μ elements νλμ νμ μ E[] μμ Object[]λ‘ λ°κΎΈλ κ²μ΄λ€.
public E pop()
{
if (size == 0) {
throw new EmptyStackException();
}
// pushμμ E νμ
λ§ νμ©νλ―λ‘ μ΄ νλ³νμ μμ νλ€.
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null; // λ€ μ΄ μ°Έμ‘° ν΄μ
return result;
}
μ΄μ elements λ₯Ό κΊΌλΌ λ μμμ Eλ‘ νλ³ννλ©΄ μ€λ₯ λμ κ²½κ³ κ° λ¨λλ°
Eλ μμ μ€μ²΄ν λΆκ° νμ μ΄λ―λ‘ μ»΄νμΌλ¬λ λ°νμμ μ΄λ€μ§λ νλ³νμ΄ μμ νμ§ μ¦λͺ ν λ°©λ²μ΄ μλ€.
νμ§λ§ μ°λ¦¬λ μ§μ μμ νμ§ μ¦λͺ νκ³ κ²½κ³ λ₯Ό μ¨κΈΈ μ μλ€.
pop λ©μλ μ 체μ κ²½κ³ λ₯Ό μ¨κΈ°μ§ λ§κ³ λ²μλ₯Ό μ΅μνν΄μ νλ³νμ μννλ ν λΉλ¬Έμλ§ μ΄λ Έν μ΄μ μ λΆμ¬ κ²½κ³ λ₯Ό μ¨κ²Όλ€.
π© μμμ μΈκΈν μ λ€λ¦ λ°°μ΄ μμ±μ μ κ±°νλ λ λ°©λ² λͺ¨λ λλ¦μ μ§μ§λ₯Ό μ»κ³ μλ€.
첫λ²μ§Έ λ°©λ²μΈ Object λ°°μ΄μ μμ±ν λ€μ μ λ€λ¦ λ°°μ΄λ‘ νλ³ν νλ λ°©λ²μ κ°λ μ±μ΄ μ’κ³ , νλ³νμ λ°°μ΄ μμ±μ ν λ²λ§ νλ€λ μ₯μ μ΄ μμΌλ©°, μ½λλ 짧λ€.
λλ²μ§Έ λ°©λ²μΈ μ λ€λ¦ λ°°μ΄ λμ μ Object λ°°μ΄μ μ¬μ©νκ³ , λ°°μ΄μ΄ λ°νν μμλ₯Ό Eλ‘ νλ³ννλ λ°©λ²μ λ°°μ΄μμ μμλ₯Ό μ½μ λ λ§λ€ νλ³νμ ν΄μ€μΌ νλ€.
λ°λΌμ νμ μμλ 첫λ²μ§Έ λ°©λ²μ λ μ νΈνλ©° μμ£Ό μ¬μ©νλ νΈμ΄λ€.
κ·Έλ°λ° 첫λ²μ§Έ λ°©λ²μ Eκ° Objectκ° μλν λ°νμ νμ μ΄ μ»΄νμΌ νμ κ³Ό λ¬λΌμ ν μ€μΌ heap pollutionμ λ°μν μ μλ€.
ν μ€μΌμ΄ 걸리λ μ¬λμ λλ²μ§Έ λ°©μμ μ¬μ©νκΈ°λ νλ€.
π μ 리
ν΄λΌμ΄μΈνΈμμ μ§μ νλ³νν΄μΌ νλ νμ λ³΄λ€ μ λ€λ¦ νμ μ΄ λ μμ νκ³ μ°κΈ° νΈνλ€.
λ°λΌμ μλ‘μ΄ νμ μ μ€κ³ν λλ νλ³ν μμ΄λ μ¬μ©ν μ μλλ‘ μ λ€λ¦ νμ μΌλ‘ λ§λ€μ!!