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
215 changes: 215 additions & 0 deletions κΉ€μˆ˜λΉˆ/6μž₯/item34.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
## item34 예제, μ—΄κ±° νƒ€μž…μ˜ μ œμ•½

ex 1. 데이터와 λ©”μ„œλ“œλ₯Ό κ°–λŠ” μ—΄κ±° νƒ€μž…

public enum Planet { MERCURY(3.302e+23, 2.439e6), VENUS (4.869e+24, 6.052e6), EARTH (5.975e+24, 6.378e6), MARS (
6.419e+23, 3.393e6), JUPITER(1.899e+27, 7.149e7), SATURN (5.685e+26, 6.027e7), URANUS (8.683e+25, 2.556e7), NEPTUNE(
1.024e+26, 2.477e7);

```java
private final double mass; // μ§ˆλŸ‰(λ‹¨μœ„: ν‚¬λ‘œκ·Έλž¨)
private final double radius; // λ°˜μ§€λ¦„(λ‹¨μœ„: λ―Έν„°)
private final double surfaceGravity; // ν‘œλ©΄μ€‘λ ₯(λ‹¨μœ„: m / s^2)

// 쀑λ ₯μƒμˆ˜(λ‹¨μœ„: m^3 / kg s^2)
private static final double G=6.67300E-11;

// μƒμ„±μž
Planet(double mass,double radius){
this.mass=mass;
this.radius=radius;
surfaceGravity=G*mass/(radius*radius);
}

public double mass(){return mass;}
public double radius(){return radius;}
public double surfaceGravity(){return surfaceGravity;}

public double surfaceWeight(double mass){
return mass*surfaceGravity; // F = ma
}
}
```

```java
public class WeightTable {
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("%sμ—μ„œμ˜ λ¬΄κ²ŒλŠ” %f이닀.%n",
p, p.surfaceWeight(mass));
}
}
```

μ—΄κ±° νƒ€μž…μ€ μžμ‹  μ•ˆμ— μ •μ˜λœ μƒμˆ˜λ“€μ˜ 값을 배열에 λ‹΄μ•„ λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ„œλ“œμΈ valuesλ₯Ό 제곡.

값듀은 μ„ μ–Έλœ μˆœμ„œλ‘œ μ €μž₯λœλ‹€. (κ·Έλ ‡λ‹€κ³  이 μˆœμ„œμ— μ˜μ‘΄ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 것은 맀우 μœ„ν—˜)

ex 2. 값에 따라 λΆ„κΈ°ν•˜λŠ” μ—΄κ±° νƒ€μž…

```java
public enum Operation {
PLUS, MINUS, TIMES, DIVDE;

public double apply(double x, double y) {
switch (this) {
case PLUS:
return x + y;
case MINUS:
return x - y;
case TIMES:
return x * y;
case DIVDE:
return x / y;
}
throw new AssertionError("μ•Œ 수 μ—†λŠ” μ—°μ‚°:" + this);
}
}
```

-> κΉ¨μ§€κΈ° μ‰¬μš΄ μ½”λ“œ : μƒˆλ‘œμš΄ μƒμˆ˜ μΆ”κ°€μ‹œ ν•΄λ‹Ή case문도 μΆ”κ°€ν•΄μ•Όν•œλ‹€. ν˜Ήμ‹œλΌλ„ κΉœλΉ‘ν•˜κ²Œ 되면 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

ex 3. μƒμˆ˜λ³„ 클래슀 λͺΈμ²΄μ™€ 데이터λ₯Ό μ‚¬μš©ν•œ μ—΄κ±° νƒ€μž…

- μ—΄κ±° νƒ€μž…μ— applyλΌλŠ” 좔상 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•˜κ³  각 μƒμˆ˜λ³„ 클래슀 λͺΈμ²΄, 즉 각 μƒμˆ˜μ—μ„œ μžμ‹ μ— 맞게 μž¬μ •μ˜ν•˜λŠ” 방법.

-> applyκ°€ 좔상 λ©”μ„œλ“œμ΄λ―€λ‘œ μž¬μ •μ˜ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ 컴파일 였λ₯˜λ‘œ μ•Œλ €μ€€λ‹€. (κΉœλΉ‘ν•  μˆ˜κ°€ μ—†λ‹€.)

```java
public enum Operation {
PLUS("+") {
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
public double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVDE("/") {
public double apply(double x, double y) {
return x / y;
}
}
}
```

```java
private final String symbol;

Operation(String symbol){
this.symbol=symbol;
}

@Override
public String toString(){
return symbol;
}

public abstract double apply(double x,double y);
}
```

ex 4. μ—΄κ±° νƒ€μž…μš© fromString λ©”μ„œλ“œ κ΅¬ν˜„ν•˜κΈ°

- toString μž¬μ •μ˜μ‹œ toString이 λ°˜ν™˜ν•˜λŠ” λ¬Έμžμ—΄μ„ ν•΄λ‹Ή μ—΄κ±° νƒ€μž… μƒμˆ˜λ‘œ λ³€ν™˜ν•΄μ£ΌλŠ” fromString λ©”μ„œλ“œ κ΅¬ν˜„λ„ κ³ λ €.

```java
private static final Map<String, Operation> stringToEnum=
Stream.of(Operation.values())
.collect(Collectors.toMap(Operation::toString,operation->operation));
// {λ¬Έμžμ—΄, μ—΄κ±° νƒ€μž… μƒμˆ˜}

//Optional둜 λ°˜ν™˜ν•˜μ—¬ 값이 μ‘΄μž¬ν•˜μ§€μ•Šμ„ 상황을 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ•Œλ¦°λ‹€.
public static Optional<Operation> fromString(String symbol){
return Optional.ofNullable(stringToEnum.get(symbol));
}

```

μ—΄κ±° νƒ€μž…μ˜ μ œμ•½

1. μƒμ„±μžμ—μ„œ μ ‘κ·Όν•  수 μžˆλŠ” 것은 μƒμˆ˜ λ³€μˆ˜λΏμ΄λ‹€.

- μ—΄κ±° νƒ€μž…μ˜ μƒμ„±μžκ°€ μ‹€ν–‰λ˜λŠ” μ‹œμ μ—λŠ” 정적 ν•„λ“œκ°€ μ΄ˆκΈ°ν™”λ˜κΈ° 전이기 λ•Œλ¬Έμ— μƒμ„±μžμ—μ„œ 정적 ν•„λ“œλ₯Ό μ°Έμ‘°ν•˜λ €κ³  μ‹œλ„ν•˜λ©΄ 컴파일 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

λ”°λΌμ„œ μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μΆ”κ°€ν•˜μ§€ λͺ»ν•˜κ²Œ ν•˜λŠ” μ œμ•½μ΄ 쑴재.

(It is illegal to access static member 'ENUM' from enum constructor or instance initializer)

μ—΄κ±° νƒ€μž… μƒμˆ˜ 생성 μˆœμ„œ

2. μ—΄κ±° νƒ€μž… μƒμˆ˜λΌλ¦¬ μ½”λ“œλ₯Ό κ³΅μœ ν•˜κΈ° μ–΄λ ΅λ‹€.

-> μ „λž΅ μ—΄κ±° νƒ€μž… νŒ¨ν„΄ (내뢀에 또 λ‹€λ₯Έ enum을 μ •μ˜ν•΄μ„œ μ„ νƒν•˜λ„)

```java
public enum PayrollDay {
MONDAY(PayType.WEEKDAY),
TUESDAY(PayType.WEEKDAY),
WEDNESDAY(PayType.WEEKDAY),
THURSDAY(PayType.WEEKDAY),
FRIDAY(PayType.WEEKDAY),
SATURDAY(PayType.WEEKEND),
SUNDAY(PayType.WEEKEND);

private final PayType payType;

PayrollDay(PayType payType) {
this.payType = payType;
}

int pay(int minutesWorked, int payRate) {
return payType.pay(minutesWorked, payRate);
}

private enum PayType {
WEEKDAY {
int overtimePay(int minutesWorked, int payRate) {
return minutesWorked <= MINS_PER_SHIFT ?
0 : (minutesWorked - MINS_PER_SHIFT) * payRate / 2;
}
},
WEEKEND {
int overtimePay(int minutesWorked, int payRate) {
return minutesWorked * payRate / 2;
}
};

abstract int overtimePay(int minutesWorked, int payRate);

private static final int MINS_PER_SHIFT = 8 * 60;

int pay(int minutesWorked, int payRate) {
int basePay = minutesWorked * payRate;
return basePay + overtimePay(minutesWorked, payRate);
}
}
}
```

3. μ½”λ“œλ₯Ό μˆ˜μ • ν•  수 μ—†λŠ” κΈ°μ‘΄ μ—΄κ±° νƒ€μž…μ— μƒμˆ˜λ³„ λ™μž‘μ„ 넣을 λ•ŒλŠ” switch문이 쒋은 선택이 될 수 μžˆλ‹€.

```java
public static Operation inverse(Operation operation){
switch(operation){
case PLUS:
return Operation.MINUS;
case MINUS:
return Operation.PLUS;
case TIMES:
return Operation.DIVDE;
case DIVDE:
return Operation.TIMES;
}
throw new AssertionError("μ•Œ 수 μ—†λŠ” μ—°μ‚° : "+operation);
}
```
91 changes: 91 additions & 0 deletions κΉ€μˆ˜λΉˆ/6μž₯/item37.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
## ordinal 인덱싱 λŒ€μ‹  EnumMap을 μ‚¬μš©ν•˜λΌ

```java
class Plant {
enum LifeCycIe {AMMUAL, PERENNIAL, BIEMMIAL}

final String name;
final LifeCycIe lifeCycle;

Plant(String name, LifeCycIe lifeCycle) {
this.name = name;
this.lifeCycle = lifeCycle;
}

@Override
public String toString() {
return name;
}
}
```

### ordinal() 을 λ°°μ—΄ 인덱슀둜 μ‚¬μš©ν•œ 예 - λ”°λΌν•˜λ©΄ μ•ˆ 됨

```java
public static void usingOrdinalArray(List<Plant> garden){
// 1. λ°°μ—΄κ³Ό μ œλ„€λ¦­μ˜ ν˜Έν™˜μ„± 문제
Set<Plant>[]plantsByLifeCycle=(Set<Plant>[])new Set[LifeCycle.values().length];
for(int i=0;i<plantsByLifeCycle.length;i++){
plantsByLifeCycle[i]=new HashSet<>();
}

for(Plant plant:garden){
// 2. μ—΄κ±° νƒ€μž…μ˜ ordinal μ‚¬μš©
plantsByLifeCycle[plant.lifeCycle.ordinal()].add(plant);
}

for(int i=0;i<plantsByLifeCycle.length;i++){
// 인덱슀의 의미λ₯Ό λͺ¨λ₯΄λ‹ˆ 좜λ ₯ 결과에 직접 λ ˆμ΄λΈ”μ„ 달아야 ν•œλ‹€
System.out.printf("%s : %s%n",LifeCycle.values()[i],plantsByLifeCycle[i]);
}
}
```

μ œλ„€λ¦­ 배열을 μƒμ„±ν•˜μ§€ λͺ»ν•˜λŠ” 이유

- ordinal() μ‚¬μš©μ‹œ : μ •μˆ˜λŠ” μ—΄κ±° νƒ€μž…κ³Ό 달리 νƒ€μž… μ•ˆμ „ν•˜μ§€ μ•ŠκΈ°λ•Œλ¬Έμ— μ •ν™•ν•œ μ •μˆ˜κ°’μ„ μ‚¬μš©ν•˜λŠ”μ§€ κ°œλ°œμžκ°€ 직접 보증해야 ν•œλ‹€. 잘λͺ»λœ 값을 μ‚¬μš©ν•˜μ—¬ 잘λͺ»λœ λ™μž‘μ„ ν•˜λ”λΌλ„ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šμ„ 수
μžˆλ‹€.

### EnumMap μ‚¬μš©

```java
public static void usingEnumMap(List<Plant> garden){Map<LifeCycle, Set<Plant>>plantsByLifeCycle=new EnumMap<>(
LifeCycle.class);

for(LifeCycle lifeCycle:LifeCycle.values()){
plantsByLifeCycle.put(lifeCycle,new HashSet<>());
}

for(Plant plant:garden){
plantsByLifeCycle.get(plant.lifeCycle).add(plant);
}
System.out.println(plantsByLifeCycle);

}
```

- 더 μ§§κ³  λͺ…λ£Œν•˜κ³  μ•ˆμ „ν•˜κ³  μ„±λŠ₯도 μ›λž˜ 버전과 λΉ„λ“±

: λ‚΄λΆ€μ μœΌλ‘œ 배열을 μ‚¬μš©ν•˜λ―€λ‘œ λ°°μ—΄μ˜ μ„±λŠ₯을 μœ μ§€ν•˜λ©΄μ„œλ„, μ—΄κ±° νƒ€μž…μ˜ νƒ€μž… μ•ˆμ •μ„±μ„ ν™œμš©

- μ•ˆμ „ν•˜μ§€ μ•Šμ€ ν˜•λ³€ν™˜μ€ μ“°μ§€ μ•Šκ³ , 맡의 킀인 μ—΄κ±° νƒ€μž…μ΄ κ·Έ 자체둜 좜λ ₯용 λ¬Έμžμ—΄μ„ 제곡

### 슀트림 μ‚¬μš©

```java
public static void streamEx1(List<Plant> garden){Map plantsByLifeCycle=garden.stream().collect(
Collectors.groupingBy(plant->plant.lifeCycle));System.out.println(plantsByLifeCycle);}

// μ„±λŠ₯ κ°œμ„ μ„ μœ„ν•΄ EnumMapκ³Ό Set μ‚¬μš© public static void streamEx2(List<Plant> garden) { Map plantsByLifeCycle = garden.stream()
.collect(Collectors.groupingBy(plant->plant.lifeCycle,
()->new EnumMap<>(LifeCycle.class),Collectors.toSet()));System.out.println(plantsByLifeCycle);}

```

- EnumMap 버전은 μ–Έμ œλ‚˜ μ‹λ¬Όμ˜ 생애주기당 ν•˜λ‚˜μ”©μ˜ 쀑첩 맡을 λ§Œλ“€μ§€λ§Œ, 슀트림 λ²„μ „μ—μ„œλŠ” ν•΄λ‹Ή 생애주기에 μ†ν•˜λŠ” 식물이 μžˆμ„ λ•Œλ§Œ λ§Œλ“ λ‹€.

### 정리

λ°°μ—΄μ˜ 인덱슀λ₯Ό μ–»κΈ° μœ„ν•΄ ordinal을 μ“°λŠ” 것은 일반적으둜 μ’‹μ§€ μ•ŠμœΌλ‹ˆ, λŒ€μ‹  EnumMap을 μ‚¬μš©ν•˜λΌ.

닀차원 κ΄€κ³„λŠ” EnumMap<..., EnumMap<...>> 으둜 ν‘œν˜„ν•˜λΌ
66 changes: 66 additions & 0 deletions κΉ€μˆ˜λΉˆ/6μž₯/item40.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## @Override μ• λ„ˆν…Œμ΄μ…˜μ„ μΌκ΄€λ˜κ²Œ μ‚¬μš©ν•˜λΌ

### @Overrideκ°€ 없을 λ•Œ ν•˜κΈ° μ‰¬μš΄ μ‹€μˆ˜

```java
public class Item40Test {
static class Bigram {
private final char first;
private final char second;

public Bigram(char first, char second) {
this.first = first;
this.second = second;
}

public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}

public int hashCode() {
return 31 * first + second;
}
}

@Test
public void bigramTest() {
Set<Bigram> s = new HashSet<>();
for (int i = 0; i < 10; i++) {
for (char ch = 'a'; ch <= 'z'; ch++) {
s.add(new Bigram(ch, ch));
}
}

Assertions.assertEquals(26, s.size()); // μ‹€μ œ κ°’ 260
}
}
```

- bigramTest() κ°€ μ›ν•œ κ²°κ³ΌλŠ” s.size()κ°€ 26인 κ²ƒμ΄μ§€λ§Œ μ‹€μ œλ‘œλŠ” 260이 λ‚˜μ™”λ‹€.
- equals()에 @Override μ• λ„ˆν…Œμ΄μ…˜μ„ 뢙이지 μ•Šμ•„μ„œ 생긴 μ‹€μˆ˜κ°€ μžˆλ‹€.
- Objectμ—μ„œ μƒμ†λ°›λŠ” equals()λŠ” μ›λž˜ Object νƒ€μž…μ˜ νŒŒλΌλ―Έν„°λ₯Ό λ°›λŠ”λ°, Bigram의 νŒŒλΌλ―Έν„°λ₯Ό λ°›κ³  μžˆλ‹€.
- κ·Έλž˜μ„œ Setμ—μ„œ 비ꡐ에 μ‚¬μš©λ˜λŠ” equals()κ°€ μ œλŒ€λ‘œ μ •μ˜λ˜μ§€ μ•Šκ³ , 였직 객체 μ£Όμ†Œμ˜ λ™μΉ˜λ§Œ λΉ„κ΅ν•˜λŠ” κΈ°λ³Έ Object의 equals()κ°€ 쓰이고 있던 것이닀.
- λ”°λΌμ„œ 같은 μ†Œλ¬Έμžλ₯Ό μ†Œμœ ν•œ λ°”μ΄κ·Έλž¨ 10개 각각이 μ„œλ‘œ λ‹€λ₯Έ 객체둜 μΈμ‹λ˜κ³ , κ²°κ΅­ 260을 좜λ ₯ν•œ 것이닀.
- μ‹€μ œ μ˜€λ²„λΌμ΄λ”©(μž¬μ •μ˜)된 것이 μ•„λ‹ˆλΌ μ˜€λ²„λ‘œλ”©μ„ ν•˜κ³  μžˆλŠ” 것이닀.

### μ‹€μˆ˜ 고치기

```java
@Override
public boolean equals(Object o){
if(!(o instanceof Bigram)){
return false;
}

Bigram b=(Bigram)o;
return b.first==first&&b.second==second;
}
```

- μœ„μ™€ 같이 @Override μ• λ„ˆν…Œμ΄μ…˜μ„ 달면, μ‹€μ œλ‘œ 상속받은 λ©”μ„œλ“œκ°€ μ•„λ‹ˆλ©΄ μ—λŸ¬λ₯Ό λ‚΄μ£ΌκΈ° λ•Œλ¬Έμ— μ‹€μˆ˜ν•  ν™•λ₯ μ΄ 적어진닀.
- 잘λͺ»ν•œ 뢀뢄을 λͺ…ν™•νžˆ μ•Œλ €μ£Όλ―€λ‘œ κ³§μž₯ μ˜¬λ°”λ₯΄κ²Œ μˆ˜μ •ν•  수 μžˆλ‹€.

### 핡심 정리

- μž¬μ •μ˜ν•œ λͺ¨λ“  λ©”μ„œλ“œμ— @Override μ• λ„ˆν…Œμ΄μ…˜μ„ 달아 μ‹€μˆ˜λ₯Ό λ°©μ§€ν•˜μž.
- 단, ꡬ체 ν΄λž˜μŠ€μ—μ„œ μƒμœ„ 클래슀의 좔상 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•œ κ²½μš°μ—” 이 μ• λ„ˆν…Œμ΄μ…˜μ„ 달지 μ•Šμ•„λ„ λœλ‹€.
Loading
Loading