Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions κΉ€μˆ˜λΉˆ/5μž₯/item28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## λ°°μ—΄λ³΄λ‹€λŠ” 리슀트λ₯Ό μ‚¬μš©ν•˜λΌ

λ°°μ—΄ vs μ œλ„€λ¦­νƒ€μž…
1. 곡변 / λΆˆκ³΅λ³€

- 배열은 곡변이닀.(ν•¨κ»˜ λ³€ν•œλ‹€)
<br>즉, Subκ°€ Super의 ν•˜μœ„ νƒ€μž…μ΄λΌλ©΄ λ°°μ—΄ Sub[]λŠ” λ°°μ—΄ Super[]의 ν•˜μœ„ νƒ€μž…μ΄ λœλ‹€.
- μ œλ„€λ¦­μ€ λΆˆκ³΅λ³€μ΄λ‹€.
<br>즉 μ„œλ‘œ λ‹€λ₯Έ νƒ€μž… Type1κ³Ό Type2κ°€ μžˆμ„ λ•Œ, List<Type1>은 List<Type2>의 ν•˜μœ„νƒ€μž…λ„ μƒμœ„νƒ€μž…λ„ μ•„λ‹ˆλ‹€.


ex 1) λ°°μ—΄κ³Ό 리슀트의 차이 1
```java
// 배열에 λ„£κΈ°
Object[] objectArray = new Long[1];
objectArray[0] = "Long에 λ¬Έμžμ—΄ λ„£κΈ°"; // λŸ°νƒ€μž„ μ‹œ ArrayStoreException λ°œμƒ

// λ¦¬μŠ€νŠΈμ— λ„£κΈ°
List<Object> objectList = new ArrayList<Long>();
objectList.add("Long에 λ¬Έμžμ—΄ λ„£κΈ°"); // 컴파일 λ‹¨κ³„μ—μ„œ 였λ₯˜ λ°œμƒ
```
- Long으둜 μ„ μ–Έλœ λ°°μ—΄κ³Ό λ¦¬μŠ€νŠΈμ— String을 넣을 수 μ—†λ‹€.
- λ°°μ—΄μ˜ 경우 λŸ°νƒ€μž„ λ•Œ 였λ₯˜λ₯Ό λ°œκ²¬ν•˜μ§€λ§Œ, λ¦¬μŠ€νŠΈλŠ” 컴파일 μ‹œμ— λ°”λ‘œ μ•Œ 수 μžˆλ‹€.


2. 싀체화

배열은 λŸ°νƒ€μž„μ—λ„ μžμ‹ μ΄ λ‹΄κΈ°λ‘œ ν•œ μ›μ†Œμ˜ νƒ€μž…μ„ μΈμ§€ν•˜κ³  ν™•μΈν•œλ‹€.
<br>μ œλ„€λ¦­μ€ μ›μ†Œνƒ€μž…μ„ μ»΄νŒŒμΌνƒ€μž„μ—λ§Œ κ²€μ‚¬ν•˜λ©°, λŸ°νƒ€μž„μ—λŠ” μ•Œμˆ˜μ‘°μ°¨ μ—†λ‹€.
<br>즉, μ œλ„€λ¦­μ€ νƒ€μž… 정보가 λŸ°νƒ€μž„μ—λŠ” μ†Œκ±°λœλ‹€.
<br>μ†Œκ±°λŠ” μ œλ„€λ¦­μ΄ μ§€μ›λ˜κΈ° μ „μ˜ λ ˆκ±°μ‹œ μ½”λ“œμ™€ μ œλ„€λ¦­ νƒ€μž…μ„ ν•¨κ»˜ μ‚¬μš©ν•  수 있게 ν•΄μ£ΌλŠ” λ§€μ»€λ‹ˆμ¦˜μœΌλ‘œ, μžλ°” 5κ°€ μ œλ„€λ¦­μœΌλ‘œ 순쑰둭게 μ „ν™˜λ  수 μžˆλ„λ‘ 함




### μœ„μ˜ μ£Όμš” μ°¨μ΄λ“€λ‘œ 인해 λ°°μ—΄κ³Ό μ œλ„€λ¦­μ€ 잘 μ–΄μš°λŸ¬μ§ˆ 수 μ—†λ‹€.

배열은 μ œλ„€λ¦­ νƒ€μž…, λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…, νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ μ‚¬μš©ν•  수 μ—†λ‹€.

ex) new List<E>[], new List<String>[], new E[] μ‹μœΌλ‘œ μž‘μ„± μ‹œ μ»΄νŒŒμΌν•  λ•Œ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.


### λ°°μ—΄λ‘œ ν˜•λ³€ν™˜ ν•  λ•Œ 였λ₯˜κ°€ λ°œμƒν•˜λŠ” 경우
λ°°μ—΄λ‘œ ν˜•λ³€ν™˜ν•  λ•Œ μ œλ„€λ¦­ λ°°μ—΄ 생성 였λ₯˜λ‚˜ 비검사 ν˜•λ³€ν™˜ κ²½κ³ κ°€ λœ¨λŠ” 경우 λŒ€λΆ€λΆ„μ€ 배열인 E[] λŒ€μ‹  μ»¬λ ‰μ…˜μΈ List<E>λ₯Ό μ‚¬μš©ν•˜λ©΄ ν•΄κ²°λœλ‹€.
<br>μ½”λ“œκ°€ 쑰금 λ³΅μž‘ν•΄μ§€κ³  μ„±λŠ₯이 살짝 λ‚˜λΉ μ§ˆ 수 μžˆμ§€λ§Œ, κ·Έ λŒ€μ‹  <code>νƒ€μž… μ•ˆμ •μ„±κ³Ό μƒν˜Έμš΄μš©μ„±</code>은 μ’‹μ•„μ§„λ‹€.

<b>ex) μ œλ„€λ¦­μ„ μ μš©ν•΄μ•Όν•˜λŠ” μ†ŒμŠ€</b>
```java
public class Chooser {
private final Object[] choiceArray;

public Chooser(Collection choices) {
this.choiceArray = choices.toArray();
}

public Object choose() {
Random rnd = ThreadLocalRandom.current();
return choiceArray[rnd.nextInt(choiceArray.length)];
}
}
```
- 이 ν΄λž˜μŠ€λŠ” μ»¬λ ‰μ…˜ μ•ˆμ˜ μ›μ†Œ 쀑 ν•˜λ‚˜λ₯Ό λ¬΄μž‘μœ„λ‘œ 선택해 λ°˜ν™˜ν•˜λŠ” choose λ©”μ„œλ“œκ°€ μžˆλ‹€.
- 이 클래슀λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ choose λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ λ°˜ν™˜λœ Objectλ₯Ό μ›ν•˜λŠ” νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•΄μ•Όν•œλ‹€.
- ν˜Ήμ‹œλ‚˜ λ‹€λ₯Έ νƒ€μž…μ˜ μ›μ†Œκ°€ λ“€μ–΄μžˆλ‹€λ©΄ λŸ°νƒ€μž„ μ‹œμ— ν˜•λ³€ν™˜μ„ ν•˜λ©° 였λ₯˜κ°€ λ°œμƒν•  것이닀.

<b> ex) μœ„ μ†ŒμŠ€λ₯Ό μ œλ„€λ¦­μœΌλ‘œ 적용</b>
```java
public class Chooser<T> {
private final T[] choiceArray;

public Chooser(Collection<T> choices) {
this.choiceArray = (T[]) choices.toArray();
}

public Object choose() {
Random rnd = ThreadLocalRandom.current();
return choiceArray[rnd.nextInt(choiceArray.length)];
}
}
```
- μœ„μ™€ 같이 μ œλ„€λ¦­μœΌλ‘œ 적용 μ‹œ, 비검사 κ²½κ³ κ°€ λ°œμƒν•œλ‹€.
- Tκ°€ 무슨 νƒ€μž…μΈ μ§€ μ•Œ 수 μ—†μœΌλ‹ˆ μ»΄νŒŒμΌλŸ¬λŠ” 이 ν˜•λ³€ν™˜μ΄ λŸ°νƒ€μž„μ—λ„ μ•ˆμ „ν•œ μ§€ 보μž₯ν•  수 μ—†λ‹€λŠ” λ©”μ‹œμ§€
- μ œλ„€λ¦­μ—μ„œλŠ” μ›μ†Œμ˜ νƒ€μž… 정보가 μ†Œκ±°λ˜μ–΄ λŸ°νƒ€μž„μ—λŠ” 무슨 νƒ€μž…μΈ μ§€ μ•Œ 수 μ—†λ‹€λŠ” 것을 κΈ°μ–΅ν•΄μ•Όν•œλ‹€.
- 이 μ†ŒμŠ€λŠ” λ™μž‘ν•˜μ§€λ§Œ, μ»΄νŒŒμΌλŸ¬κ°€ μ•ˆμ „μ„ 보μž₯ν•˜μ§€ λͺ»ν•œλ‹€.
- 이 κ²½κ³ λ₯Ό μ œκ±°ν•˜λ €λ©΄, λ°°μ—΄ λŒ€μ‹  리슀트λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

<b> ex) 리슀트둜 적용</b>
```java
class Chooser<T> {
private final List<T> choiceList;

public Chooser(Collection<T> choices) {
this.choiceList = new ArrayList<>(choices);
}

public T choose() {
Random rnd = ThreadLocalRandom.current();
return choiceList.get(rnd.nextInt(choiceList.size()));
}
}
```
- μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§€κ³  쑰금 λŠλ €μ‘Œκ² μ§€λ§Œ, λŸ°νƒ€μž„ μ‹œ ClassCastException을 ν”Όν•  수 μžˆλ‹€.

### 정리
- 배열은 곡변이고 μ‹€μ²΄ν™”λ˜μ–΄ λŸ°νƒ€μž„ μ‹œ νƒ€μž… μ•ˆμ „ν•˜μ§€ μ•Šμ§€λ§Œ, 컴파일 μ‹œμ—λŠ” κ·Έλ ‡μ§€ μ•Šλ‹€.
- 반면, μ œλ„€λ¦­μ€ λΆˆκ³΅λ³€μ΄κ³  νƒ€μž… 정보가 μ†Œκ±°λ˜μ–΄ κ·Έ λ°˜λŒ€λ‹€.
- μœ„μ™€ 같은 νŠΉμ„±μœΌλ‘œ 인해 λ‘˜μ„ μ„žμ–΄μ“°κΈ°λŠ” 쉽지 μ•ŠμœΌλ©°, λ‘˜μ„ μ„žμ–΄ μ‚¬μš©ν•˜λ‹€κ°€ 였λ₯˜λ‚˜ κ²½κ³ λ₯Ό λ§Œλ‚˜λ©΄ 배열을 리슀트둜 λŒ€μ²΄ν•΄λ³΄μž.
166 changes: 166 additions & 0 deletions κΉ€μˆ˜λΉˆ/5μž₯/item29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
## 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ



클래슀 μ•ˆμ— λ‹€λ₯Έ 객체듀을 λ‹΄λŠ” 역할을 ν•˜λŠ” ν΄λž˜μŠ€λ“€μ€ <code>μ œλ„€λ¦­ νƒ€μž…</code>으둜 λ§Œλ“€λ©΄ μœ μš©ν•˜λ‹€.

ex) stack

- μ œλ„€λ¦­μ„ μ‚¬μš©ν• λ•Œ μž₯점

- ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ—μ„œ ν˜• λ³€ν™˜ 을 μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ λ§Œλ“€ 수 μžˆλ‹€.

- λ˜ν•œ ν˜• λ³€ν™˜ 을 잘λͺ» μ‚¬μš©ν–ˆμ„ λ•Œ λ°œμƒν•  수 μžˆλŠ” <code>ClassCastException</code> 을 미연에 λ°©μ§€ ν•  수 μžˆλ‹€.
```java
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;
}

public boolean isEmpty() {
return size == 0;
}

private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
```

### μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ³€κ²½ν•˜λŠ” 두 κ°€μ§€ 방법

1. 배열을 λ§Œλ“€λ•Œ ν˜• λ³€ν™˜μ„ 1번만 ν•˜λŠ” 방법

- Stack<E> 둜 μ œλ„€λ¦­ νƒ€μž…μ„ μ„ μ–Έν•œ λ’€ E[] μ œλ„€λ¦­ νƒ€μž…μ˜ 배열을 μ‚¬μš©

- μ œλ„€λ¦­ 배열을 λ§Œλ“€ 수 μ—†κΈ° λ•Œλ¬Έμ— Object 배열을 λ§Œλ“  λ’€ E[] μ œλ„€λ¦­ νƒ€μž…μ˜ λ°°μ—΄λ‘œ ν˜• λ³€ν™˜ 을 ν•΄μ€˜μ•Όν•œλ‹€.

- 런 νƒ€μž„ μ—λŠ” E[] 뢀뢄이 μ†Œκ±° 되기 λ•Œλ¬Έμ— κ²°κ΅­ Object νƒ€μž…μ˜ λ°°μ—΄λ‘œ λ™μž‘ν•˜κ²Œ λœλ‹€.
- λ°°μ—΄μ˜ λŸ°νƒ€μž„ νƒ€μž…( Object )이 μ»΄νŒŒμΌνƒ€μž…( E ) κ³Ό 달라 <code>νž™ μ˜€μ—Ό</code>을 μΌμœΌν‚€λŠ” 단점
```java
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;

// λ°°μ—΄ elementsλŠ” push(E)둜 λ„˜μ–΄μ˜¨ E μΈμŠ€ν„΄μŠ€λ§Œ λ‹΄λŠ”λ‹€.
// λ”°λΌμ„œ νƒ€μž… μ•ˆμ „μ„±μ„ 보μž₯ν•˜μ§€λ§Œ,
// 이 λ°°μ—΄μ˜ λŸ°νƒ€μž„ νƒ€μž…μ€ E[]κ°€ μ•„λ‹Œ Object[]λ‹€!
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[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;
}

public boolean isEmpty() {
return size == 0;
}

private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
```



2. νž™ μ˜€μ—Όμ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ” 방법

- μ œλ„€λ¦­ λ°°μ—΄(E[]) λŒ€μ‹  Object 배열을 μ‚¬μš©

- λŒ€μ‹  λ‹΄μ•„λ’€λ˜ 객체λ₯Ό κΊΌλ‚Ό λ•Œ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ ν˜• λ³€ν™˜ 을 ν•΄μ•Όν•œλ‹€.
```java
public class Stack<E> {
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(E e) {
ensureCapacity();
elements[size++] = e;
}

// 비검사 κ²½κ³ λ₯Ό 적절히 μˆ¨κΈ΄λ‹€.
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 == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
```

### νž™μ˜€μ—Ό

νž™ λ©”λͺ¨λ¦¬μ˜ 데이터 <code>νƒ€μž… μ•ˆμ „μ„±(type safety)</code>이 μ†μƒλ˜λŠ” 상황

νž™ λ©”λͺ¨λ¦¬μ— μ €μž₯된 객체의 μ‹€μ œ νƒ€μž…κ³Ό μ»΄νŒŒμΌλŸ¬κ°€ μ˜ˆμƒν•˜λŠ” νƒ€μž…μ΄ λΆˆμΌμΉ˜ν•˜κ²Œ λœλ‹€.

μ΄λŠ” 보톡 μ œλ„€λ¦­ νƒ€μž…μ˜ λΆˆλ³€μ„±μ„ μœ„λ°˜ν•˜κ±°λ‚˜, raw type(λΉ„μ œλ„€λ¦­ νƒ€μž…)을 μ‚¬μš©ν•  λ•Œ λ°œμƒν•˜λ©°, λŸ°νƒ€μž„ μ‹œμ— ClassCastExceptionκ³Ό 같은 였λ₯˜λ₯Ό μΌμœΌν‚¬ κ°€λŠ₯성을 λ†’μž„.

νž™ μ˜€μ—ΌμœΌλ‘œ 인해 νž™ λ©”λͺ¨λ¦¬μ˜ νƒ€μž… 정보와 μ‹€μ œ μ €μž₯된 객체 νƒ€μž…μ΄ λΆˆμΌμΉ˜ν•˜λ©΄:

- ν”„λ‘œκ·Έλž¨μ˜ νƒ€μž… μ•ˆμ •μ„±μ΄ 손상,
- λŸ°νƒ€μž„ μ˜ˆμ™Έ(ClassCastException)κ°€ λ°œμƒ,
- JVM의 λ©”λͺ¨λ¦¬ 관리와 μ΅œμ ν™”μ— 뢀정적인 영ν–₯을 쀄 수 있음


### 정리

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 직접 ν˜•λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” νƒ€μž…λ³΄λ‹€ μ œλ„€λ¦­ νƒ€μž…μ΄ 더 μ•ˆμ „ν•˜κ³  μ“°κΈ° νŽΈν•˜λ‹€.

κ·ΈλŸ¬λ‹ˆ μƒˆλ‘œμš΄ νƒ€μž…μ„ 섀계할 λ•ŒλŠ” ν˜•λ³€ν™˜ 없이도 μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜λΌ.

κ·Έλ ‡κ²Œ ν•˜λ €λ©΄ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€μ–΄μ•Ό ν•  κ²½μš°κ°€ λ§Žλ‹€.

κΈ°μ‘΄ νƒ€μž… 쀑 μ œλ„€λ¦­μ΄μ—ˆμ–΄μ•Ό ν•˜λŠ” κ²Œμžˆλ‹€λ©΄ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ³€κ²½ν•˜μž.


50 changes: 50 additions & 0 deletions κΉ€μˆ˜λΉˆ/5μž₯/item30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## 이왕이면 μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ§Œλ“€λΌ

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

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





<b>ex) 두 μ§‘ν•©μ˜ 합집합을 λ°˜ν™˜ν•˜λŠ” μ½”λ“œ(문제 λ°œμƒ)</b>
```java
public static Set union(Set s1, Set s2) {
Set result = new HashSet<>();
result.addAll(s2);
return result;
}
```
- μœ„μ˜ μ½”λ“œλŠ” μ»΄νŒŒμΌμ€ λ˜μ§€λ§Œ κ²½κ³ κ°€ 2개 λ°œμƒν•œλ‹€.
- κ²½κ³ λ₯Ό μ—†μ• λ €λ©΄ 이 λ©”μ„œλ“œλ₯Ό νƒ€μž… μ•ˆμ „ν•˜κ²Œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.
- λ©”μ„œλ“œ μ„ μ–Έμ—μ„œμ˜ μ„Έ μ§‘ν•©(μž…λ ₯ 2개, λ°˜ν™˜ 1κ±”)의 μ›μ†Œνƒ€μž…μ„ νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ λͺ…μ‹œν•˜κ³ , λ©”μ„œλ“œ μ•ˆμ—μ„œλ„ 이 νƒ€μž… λ§€κ°œλ³€μˆ˜λ§Œ μ‚¬μš©ν•˜κ²Œ μˆ˜μ •ν•˜λ©΄ λœλ‹€.
- (νƒ€μž… λ§€κ°œλ³€μˆ˜λ“€μ„ μ„ μ–Έν•˜λŠ”) νƒ€μž… λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ€ λ©”μ„œλ“œμ˜ μ œν•œμžμ™€ λ°˜ν™˜ νƒ€μž… 사이에 μ˜¨λ‹€.




<b>ex) μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ³€κ²½ν•œ μ½”λ“œ</b>
```java
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<String> aflCio = union(guys, stooges);
System.out.println(aflCio);
}
```
- 이 μ½”λ“œλŠ” 경고없이 컴파일 되며, νƒ€μž… μ•ˆμ „ν•˜κ³  μ‚¬μš©ν•˜κΈ°λ„ 쉽닀.
- union λ©”μ„œλ“œμ˜ μ§‘ν•© 3개(μž…λ ₯ 2개, λ°˜ν™˜ 1개)의 νƒ€μž…μ΄ λͺ¨λ‘ κ°™μ•„μ•Ό ν•œλ‹€.
- ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ 더 μœ μ—°ν•˜κ²Œ κ°œμ„ ν•  수 μžˆλ‹€. (μ•„μ΄ν…œ 31)

### 정리
- μ œλ„€λ¦­ νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ, ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μž…λ ₯ λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ„ λͺ…μ‹œμ μœΌλ‘œ ν˜•λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” λ©”μ„œλ“œλ³΄λ‹€ μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ 더 μ•ˆμ „ν•˜κ³  μ‚¬μš©ν•˜κΈ° 쉽닀.
- νƒ€μž…κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ, λ©”μ„œλ“œλ„ ν˜•λ³€ν™˜ 없이 μ‚¬μš©ν•  수 μžˆλŠ” 편이 μ’‹μœΌλ©° λ§Žμ€ 경우 κ·Έλ ‡κ²Œ ν•˜λ €λ©΄ μ œλ„€λ¦­ λ©”μ„œλ“œκ°€ λ˜μ–΄μ•Ό ν•œλ‹€.
- ν˜•λ³€ν™˜μ„ ν•΄μ€˜μ•Ό ν•˜λŠ” κΈ°μ‘΄ λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ν•˜κ²Œ λ§Œλ“€μ–΄ 주자.
Loading