34. int ์์ ๋์ ์ด๊ฑฐ ํ์ ์ฌ์ฉํ๊ธฐ
์ด๊ฑฐ ํ์ = ์ผ์ ๊ฐ์์ ์์ ๊ฐ์ ์ ์ํ ๋ค์, ๊ทธ ์ธ์ ๊ฐ์ ํ์ฉํ์ง ์๋ ํ์
โด๏ธ ์ด๊ฑฐ ํจํด์ ๋จ์
- ํ์ ์์ ๋ณด์ฅ X
- ํํ๋ ฅ ์ข์ง X
- ํ๋ฒํ ์์๋ฅผ ๋์ดํ ๊ฒ์ด๋ผ ์์์ ๊ฐ์ด ๋ฐ๋๋ฉด ํด๋ผ์ด์ธํธ๋ ๋ฐ๋์ ๋ค์ ์ปดํ์ผํด์ผ ํจ
- ์ ์ ์์๋ ๋ฌธ์์ด๋ก ์ถ๋ ฅํ๊ธฐ ๊น๋ค๋ก์
๐ ์ด๊ฑฐ ํ์ (ENUM type)์ด ๋์
public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}
โณ๏ธ ์ด๊ฑฐ ํ์
- ์ด๊ฑฐ ํ์ ์์ฒด๋ ํด๋์ค
- ์์ ํ๋๋น ์์ ์ ์ธ์คํด์ค๋ฅผ ํ๋์ฉ ๋ง๋ค์ด public static final ํ๋๋ก ๊ณต๊ฐ
- ๋ฐ์์ ์ ๊ทผํ ์ ์๋ ์์ฑ์๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ์ฌ์ค์ final
- ํด๋ผ์ด์ธํธ๊ฐ ์ธ์คํด์ค๋ฅผ ์ง์ ์์ฑํ๊ฑฐ๋ ํ์ฅํ ์ ์์ผ๋ฏ๋ก ์ด๊ฑฐ ํ์
์ ์ธ์ผ๋ก ๋ง๋ค์ด์ง ์ธ์คํด์ค๋ค์ ๋ฑ ํ๋์ฉ๋ง ์กด์ฌ ๋ณด์ฅ
= ์ธ์คํด์ค ํต์ - ์ปดํ์ผํ์ ํ์ ์์ ์ฑ ์ ๊ณต
- ๊ฐ์์ ์ด๋ฆ ๊ณต๊ฐ์ด ์์ด์ ์ด๋ฆ์ด ๊ฐ์ ์์๋ ๊ณต์กด ๊ฐ๋ฅ
enum Color {
RED, GREEN, BLUE
}
enum Direction {
NORTH, SOUTH, EAST, WEST, RED
}
// Color.RED์ Direction.RED -> ๊ณต์กด ๊ฐ๋ฅ
- toString ๋ฉ์๋๋ก ๋ฌธ์์ด ์ถ๋ ฅ
- toString ๋ฉ์๋ ์ฌ์ ์ํ ์ toString์ด ๋ฐํํ๋ ๋ฌธ์์ด์ ํด๋น ์ด๊ฑฐ ํ์ ์์๋ก ๋ณํํด์ฃผ๋ fromString ๋ฉ์๋๋ ํจ๊ป ์ ๊ณตํ๊ธฐ !
- ์์์ ๋ฉ์๋๋ ํ๋ ์ถ๊ฐ ๊ฐ๋ฅ
- ์์์ ์ธํฐํ์ด์ค ๊ตฌํ ๊ฐ๋ฅ
// ๋ฐ์ดํฐ์ ๋ฉ์๋๋ฅผ ๊ฐ๋ ์ด๊ฑฐ ํ์
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7);
private final double mass; // ํ์ฑ์ ์ง๋ (ํฌ๋ก๊ทธ๋จ)
private final double radius; // ํ์ฑ์ ๋ฐ์ง๋ฆ (๋ฏธํฐ)
private final double surfaceGravity; // ํ์ฑ์ ํ๋ฉด ์ค๋ ฅ
// ์ค๋ ฅ ์์ (๋จ์: m^3 / kg s^2)
private static final double G = 6.67300E-11;
// ์ด๊ฑฐํ ์์ฑ์
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
this.surfaceGravity = G * mass / (radius * radius);
}
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
public double getSurfaceGravity() {
return surfaceGravity;
}
// ์ฃผ์ด์ง ์ง๋์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฑ์์์ ๋ฌด๊ฒ๋ฅผ ๊ณ์ฐ
public double surfaceWeight(double mass) {
return mass * surfaceGravity;
}
public static void main(String[] args) {
double earthWeight = 70.0; // ์์๋ก ์ง๊ตฌ์์ 70kg์ธ ์ฌ๋
double mass = earthWeight / Planet.EARTH.getSurfaceGravity();
for (Planet p : Planet.values()) {
System.out.printf("Weight on %s: %.2f N%n", p, p.surfaceWeight(mass));
}
}
}
๐ ์ด๊ฑฐ ํ์
์์ ๊ฐ๊ฐ์ ํน์ ๋ฐ์ดํฐ์ ์ฐ๊ฒฐ ์ง์ผ๋ ค๋ฉด ์์ฑ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ธ์คํด์ค ํ๋์ ์ ์ฅํ๋ฉด ๋จ
ํ๋๋ฅผ public์ผ๋ก ์ ์ธํด๋ ๋์ง๋ง, private์ผ๋ก ๋๊ณ ๋ณ๋์ public ์ ๊ทผ์ ๋ฉ์๋๋ฅผ ๋๋๊ฒ ๋์ ! (์์ดํ
16)
- ์ด๊ฑฐ ํ์ ์ ์์ ์์ ์ ์๋ ์์๋ค์ ๊ฐ์ ๋ฐฐ์ด์ ๋ด์ ๋ฐํํ๋ ์ ์ ๋ฉ์๋์ธ values ์ ๊ณต ๐ ๊ฐ๋ค์ ์ ์ธ๋ ์์๋ก ์ ์ฅ๋จ
โณ๏ธ ์์๋ณ ๋ฉ์๋ ๊ตฌํ์ ํ์ฉํ ์ด๊ฑฐ ํ์
public enum Operation {
ADD {public double apply(double x, double y) {return x + y;}},
SUBTRACT {public double apply(double x, double y) {return x - y;}},
MULTIPLY { public double apply(double x, double y) {return x * y;}},
DIVIDE {public double apply(double x, double y) {return x / y;}};
// ๊ฐ ์์๋ณ๋ก ๊ตฌํ๋ ์ถ์ ๋ฉ์๋
public abstract double apply(double x, double y);
}
- ๋จ์
- ์ด๊ฑฐ ํ์ ์์๋ผ๋ฆฌ ์ฝ๋ ๊ณต์ ์ด๋ ค์
enum PayrollDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
SATURDAY, SUNDAY;
private static final int MINS_PER_SHIFT = 8 * 60;
int pay(int minutesWorked, int payRate){
int basePay = minutesWorked * payRate;
int overtimePay;
switch(this){
case SATURDAY: case SUNDAY: // ์ฃผ๋ง -> ๋ฌด์กฐ๊ฑด ์์
์๋น์ด ์ฃผ์ด์ง
overtimePay = basePay/2;
break;
default: // ์ฃผ์ค -> ์ค๋ฒํ์ ๋ฐ์ ์ ์์
์๋น ์ฃผ์ด์ง
overtimePay = minutesWorked <= MINS_PER_SHIFT ?
0 : (minutesWorked - MINS_PER_SHIFT) * payRate / 2;
}
return basePay + overtimePay;
}
}
๐ ํด๊ฐ์ ๊ฐ์ ์๋ก์ด ๊ฐ์ ์ด๊ฑฐ ํ์ ์ ์ถ๊ฐํ๋ ค๋ฉด ๊ทธ ๊ฐ์ ์ฒ๋ฆฌํ๋ case๋ฌธ์ ์์ง ๋ง๊ณ ์์ผ๋ก ๋ฃ์ด์ค์ผ ํจใ ใ
โณ๏ธ ์ ๋ต ์ด๊ฑฐ ํ์ ํจํด
- ์์ ๊ฐ์ ์์์์ ์๋ก์ด ์์๋ฅผ ์ถ๊ฐํ ๋ ์์ ์๋น '์ ๋ต' ์ ํ
- ์์ ์๋น ๊ณ์ฐ์ private ์ค์ฒฉ ์ด๊ฑฐ ํ์ ์ผ๋ก ์ฎ๊ธฐ๊ณ , PayrollDay ์ด๊ฑฐ ํ์ ์ ์์ฑ์์์ ์ด์ค ์ ๋นํ ๊ฒ ์ ํ
- PayrollDay ์ด๊ฑฐ ํ์ ์ ์์ ์๋น ๊ณ์ฐ์ ๊ทธ ์ ๋ต ์ด๊ฑฐ ํ์ ์ ์์ํ์ฌ, switch ๋ฌธ์ด๋ ์์๋ณ ๋ฉ์๋ ๊ตฌํ์ด ํ์ X
enum PayrollDay{
MONDAY(WEEKDAY), TUESDAY(WEEKDAY), WEDNESDAY(WEEKDAY),
THURSDAY(WEEKDAY), FRIDAY(WEEKDAY), SATURDAY(WEEKEND), SUNDAY(WEEKEND);
private final PayType payType;
PayrollDay(PayType payType) {this.payType = payType;}
int pay(int minutesWorked, int payRate){
return payType.pay(minutesWorked, payRate);
}
// ์ ๋ต ์ด๊ฑฐ ํ์
enum PayType{
WEEKDAY{
int overtimePay(int minutesWorked, int payRate){
return minsWorked <= MINS_PER_SHIFT ? 0 :
(minsWorked - MINS_PER_SHIFT) * payRate / 2;
}
},
WEEKEND {
int overtimePay(int minutesWorked, int payRate){
return minsWorked * payRate / 2;
}
};
abstract int overtimePay(int mins, int payRate);
private static final int MINS_PER_SHIFT = 8 * 60;
int pay(int minsWorked, int payRate){
int basePay = minsWorked * payRate;
return basePay + overtimePay(minsWorked, payRate);
}
}
}
public class PayrollSystem {
public static void main(String[] args) {
// ๊ฐ ๋ ์ ๋ํด ๊ทผ๋ฌดํ ์๊ฐ๊ณผ ๊ธ์ฌ์จ์ ์ค์
int payRate = 10; // ๋ถ๋น ๊ธ์ฌ์จ (์: 10 ๋จ์)
// ๊ฐ ์์ผ์ ๋ํ ๊ทผ๋ฌด ์๊ฐ
int minutesWorkedMonday = 480; // 8์๊ฐ
int minutesWorkedSaturday = 600; // 10์๊ฐ
int minutesWorkedSunday = 120; // 2์๊ฐ
// ๊ธ์ฌ ๊ณ์ฐ
int mondayPay = PayrollDay.MONDAY.pay(minutesWorkedMonday, payRate);
int saturdayPay = PayrollDay.SATURDAY.pay(minutesWorkedSaturday, payRate);
int sundayPay = PayrollDay.SUNDAY.pay(minutesWorkedSunday, payRate);
// ๊ฒฐ๊ณผ ์ถ๋ ฅ
System.out.println("Monday Pay: $" + mondayPay); // ์ถ๋ ฅ: Monday Pay: $80
System.out.println("Saturday Pay: $" + saturdayPay); // ์ถ๋ ฅ: Saturday Pay: $50
System.out.println("Sunday Pay: $" + sundayPay); // ์ถ๋ ฅ: Sunday Pay: $20
}
}
โจ ๊ฒฐ๋ก ์ ์ผ๋ก, ์ด๊ฑฐ ํ์ ์ ์ธ์ ์จ์ผ ํ๋..?
๐ ํ์ํ ์์๋ฅผ ์ปดํ์ผ ํ์์ ๋ค ์ ์ ์๋ ์์ ์งํฉ์ด๋ผ๋ฉด ํญ์ ์ด๊ฑฐ ํ์ ์ฌ์ฉํ๊ธฐ !
์ด๊ฑฐ ํ์ ์ ์ ์๋ ์์ ๊ฐ์๊ฐ ์์ํ ๊ณ ์ ๋ถ๋ณ์ผ ํ์ X
35. ordinal ๋ฉ์๋ ๋์ ์ธ์คํด์ค ํ๋ ์ฌ์ฉํ๊ธฐ
๋๋ถ๋ถ์ ์ด๊ฑฐ ํ์ ์์๋ ํ๋์ ์ ์ซ๊ฐ์ ๋์ํ๋ฉฐ ํด๋น ์์๊ฐ ๊ทธ ์ด๊ฑฐ ํ์ ์์ ๋ช ๋ฒ์งธ ์์น์ธ์ง ๋ฐํํ๋ ordinal ๋ฉ์๋ ์ ๊ณต
๐ ์ ์ง๋ณด์ ๋ฐ ์ค์ฉ์ฑ์ด ๋จ์ด์ง
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPTET, OCTET, NONET, DECET;
public int numberOfMusicians() { return ordinal() + 1; }
}
ordinal ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ ๋ ๋จ์ ์ด ์๋ค.
- ์์ ์์์ ์์กด ๐ ์๋ก์ด ์์๋ฅผ ์ค๊ฐ์ ์ถ๊ฐํ๊ฑฐ๋ ์์๋ฅผ ๋ฐ๊พธ๋ฉด ๊ธฐ์กด์ ordinal ๊ฐ๋ ๋ฐ๋
- ์๋ฏธ ๋ถ์กฑ
- ์ค๊ฐ์ ๊ฐ์ ๋น์๋ ์ ์์
- ๊ฐ๋ ์ฑ ์ ํ
public enum Ensemble {
SOLO(1), DUET(2), TRIO(3), QUARTET,(4) QUINTET(5),
SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8), // ์ด๋ฏธ ์ฌ์ฉ์ค์ธ ์์๊ฐ ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ
NONET(9), DECET(10), TRIPLE_QUARTET(12); // ์ค๊ฐ์ ๊ฐ์ ๋น์ธ ์ ์์
private final int numberOfMusicians;
Ensemble(int size) { this.numberOfMusicians = size; }
public int numberOfMusicians() { return ordinal() + 1; }
}
36. ๋นํธ ํ๋ ๋์ EnumSet ์ฌ์ฉํ๊ธฐ
- ๋นํธ ํ๋ ์ฌ์ฉ ์ ๋นํธ๋ณ ์ฐ์ฐ์ ์ฌ์ฉํด ํฉ์งํฉ๊ณผ ๊ต์งํฉ ๊ฐ์ ์งํฉ ์ฐ์ฐ์ ํจ์จ์ ์ผ๋ก ์ํ ๊ฐ๋ฅ
- ์ ์ ์ด๊ฑฐ ์์์ ๋จ์ ์ ๊ทธ๋๋ก ์ง๋๋ฉฐ ํด์ํ๊ธฐ ์ด๋ ค์
- ์ต๋ ๋ช ๋นํธ๊ฐ ํ์ํ์ง๋ฅผ API ์์ฑ ์ ๋ฏธ๋ฆฌ ์์ธกํ์ฌ ์ ์ ํ ํ์ ์ ์ ํํด์ผ ํจ
public class Text{
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
public static final int STYLE_UNDERLINE = 1 << 2; // 4
public static final int STYLE_STRIKETHROUGH = 1 << 3; // 5
public void applyStyle(int styles){...}
}
โณ๏ธ EnumSet
- Set ์ธํฐํ์ด์ค ๊ตฌํ
- ํ์ ์์ ํ๊ณ ๋ค๋ฅธ ์ด๋ค Set ๊ตฌํ์ฒด์๋ ํจ๊ป ์ฌ์ฉ ๊ฐ๋ฅ
public class Text {
public enum Style {BOLD, ITALIC, UNDERLINE, STRIKETHROUGH}
// Set์ ๋๊น
public void applyStyles(Set<Style> styles) {...}
public static void main(String[] args) {
Text text = new Text();
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
}
}
- ์ applyStyles ๋ฉ์๋๋ EnumSet์ด ์๋ Set์ ๋ฐ์์๊น...
๐ ์ข ํน์ดํ ํด๋ผ์ด์ธํธ๊ฐ ๋ค๋ฅธ Set ๊ตฌํ์ฒด๋ฅผ ๋๊ธฐ๋๋ผ๋ ์ฒ๋ฆฌ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ !
37. ordinal ์ธ๋ฑ์ฑ ๋์ EnumMap ์ฌ์ฉํ๊ธฐ
class Plant {
enum LifeCycle {
ANNUAL, PERENNIAL, BIENNIAL // ํํด์ด์ด, ์ฌ๋ฌํด์ด์ด, ๋ํด์ด์ด
}
final String name;
final LifeCycle lifeCycle;
public Plant(String name, LifeCycle lifeCycle) {
this.name = name;
this.lifeCycle = lifeCycle;
}
@Override
public String toString() {
return name;
}
}
์ ์์ ์ฌ์ ์๋ฌผ๋ค์ ๋ฐฐ์ด ํ๋๋ก ๊ด๋ฆฌํ๊ณ , ์ด๋ค์ ์์ ์ฃผ๊ธฐ๋ณ๋ก ๋ฌถ์ ๋ ์ด 3๊ฐ์ ์งํฉ(ํํด, ์ฌ๋ฌํด, ๋ํด)์ ๋ง๋ค๊ณ ์ ์์ ์๋ ๊ฐ ์๋ฌผ์ ํด๋น ์งํฉ์ ๋ฃ์ผ๋ฉด ๋๋ค.
private void plantClassification(Plant[] garden) {
Map<Plant.LifeCycle, Set<Plant>> plantsByLifeCycle = new EnumMap<>(Plant.LifeCycle.class);
for (Plant.LifeCycle lc : Plant.LifeCycle.values()) {
plantsByLifeCycle.put(lc, new HashSet<>());
}
for (Plant p : garden) {
plantsByLifeCycle.get(p.lifeCycle).add(p);
}
System.out.println(plantsByLifeCycle);
}
// ์ถ๋ ฅ๊ฒฐ๊ณผ
// {ANNUAL=[Marigold, Sunflower], PERENNIAL=[Rose, Tulip], BIENNIAL=[Parsley]}
- ๋ด๋ถ์์ ๋ฐฐ์ด์ ์ฌ์ฉํ๊ณ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์์ ์์ผ๋ก ์จ๊ฒจ์ Map์ ํ์ ์์ ์ฑ๊ณผ ๋ฐฐ์ด์ ์ฑ๋ฅ์ ๋ชจ๋ ์ป์ด๋
- ๋งต์ ํค์ธ ์ด๊ฑฐ ํ์ ์ด ๊ทธ ์์ฒด๋ก ์ถ๋ ฅ์ฉ ๋ฌธ์์ด ์ ๊ณต
โณ๏ธ ์คํธ๋ฆผ์ ์ฌ์ฉํ ์ฝ๋ - EnumMap์ ์ด์ฉํด ๋ฐ์ดํฐ์ ์ด๊ฑฐ ํ์ ๋งคํ
System.out.println(Arrays.stream(garden)
.collect(groupingBy(p -> p.lifeCycle,
() -> new EnumMap<>(LifeCycle.class), toSet())));
- ๋ง์ฝ ํํด์ด์ด์ ์ฌ๋ฌํด์ด์ด ์๋ฌผ๋ง ์ด๊ณ ๋ํด์ด์ด๋ ์๋ค๋ฉด EnumMap ๋ฒ์ ์์๋ ๋งต์ 3๊ฐ ๋ง๋ค๊ณ , ์คํธ๋ฆผ ๋ฒ์ ์์๋ 2๊ฐ๋ง ๋ง๋ฆ
โณ๏ธ ordinal ๋ ๋ฒ ์ฐ๊ธฐ ...?
public enum Phase {
SOLID, LIQUID, GAS; //๊ณ ์ฒด, ์ก์ฒด, ๊ธฐ์ฒด
public enum Transition {
MELT, FREEZE, BOIL, CONDENSE, SUBLIME, DEPOSIT; // ์ตํด, ์๊ณ , ๊ธฐํ, ์๊ฒฐ, ์นํ, ์นํ
// ํ์ from์ ordinal์, ์ด์ to์ ordinal์ ์ธ๋ฑ์ค๋ก ์ฌ์ฉ
private static final Transition[][] TRANSITIONS = {
{ null, MELT, SUBLIME }, // ๊ณ ์ฒด๋ ์ตํด, ์นํ
{ FREEZE, null, BOIL }, // ์ก์ฒด๋ ์๊ณ , ๊ธฐํ
{ DEPOSIT, CONDENSE, null }, // ๊ธฐ์ฒด๋ ์นํ, ์๊ฒฐ
};
public static Transition from(Phase from, Phase to) {
return TRANSITIONS[from.ordinal()][to.ordinal()];
}
}
}
- Phase๋ Phase.Transition ์ด๊ฑฐ ํ์ ์ ์์ ํ๋ฉด์ ์์ ์ด ํ TRANSITIONS๋ฅผ ํจ๊ป ์์ ํ์ง ์๊ฑฐ๋ ์ค์๋ก ์๋ชป ์์ ํ๋ค๋ฉด ๋ฐํ์ ์ค๋ฅ ๋ฐ์
โณ๏ธ ์ค์ฒฉ EnumMap์ผ๋ก ๋ฐ์ดํฐ์ ์ด๊ฑฐ ํ์ ์์ ์ฐ๊ฒฐ
public enum Phase {
SOLID, LIQUID, GAS;
public enum Transition {
MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID),
BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID),
SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
private final Phase from;
private final Phase to;
Transition(Phase from, Phase to) {
this.from = from;
this.to = to;
}
// ์์ ์ด ๋งต ์ด๊ธฐํ
private static final Map<Phase, Map<Phase, Transition>> m =
Stream.of(values()).collect(groupingBy(t -> t.from,() -> new EnumMap<>(Phase.class),
toMap(t -> t.to, t -> t,
(x, y) -> y, () -> new EnumMap<>(Phase.class))));
public static Transition from(Phase from, Phase to) {
return m.get(from).get(to);
}
}
}
- ์์ชฝ ๋งต์ ์ด์ ์ํ์ ์ ์ด๋ฅผ ์ฐ๊ฒฐ
- ๋ฐ๊นฅ์ชฝ ๋งต์ ์ดํ ์ํ์ ์์ชฝ ๋งต ์ฐ๊ฒฐ
- groupingBy ๐ ์ ์ด๋ฅผ ์ด์ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฌถ์
- toMap ๐ ์ดํ ์ํ๋ฅผ ์ ์ด์ ๋์์ํค๋ EnumMap ์์ฑ
- (x, y) -> y๋ ์ ์ธ๋ง ํ๊ณ ์ค์ ๋ก๋ ์ฐ์ด์ง ์์
- Transition.from(Phase.SOLID, Phase.LIQUID)๋ฅผ ํธ์ถํ๋ฉด Transition.MELT๊ฐ ๋ฐํ
์์ ์ด ๋งต์ ์ด๊ธฐํํ๋ ์ฝ๋๋ ์ ๋ฒ ๋ณต์กํ์ง๋ง, ์๋ก์ด ์ํ์ธ PLASMA๋ฅผ ์ถ๊ฐํ๊ฒ ๋๋ค๋ฉด
์ํ๋ชฉ๋ก์ PLASMA๋ฅผ ์ถ๊ฐํ๊ณ , ์ ์ด ๋ชฉ๋ก์ IONIZE(GAS, PLASMA)์ DEIONIZE(PLASMA, GAS)๋ง ์ถ๊ฐํ๋ฉด ๋จ
โจ Collectors.groupingBy() ๋ฉ์๋๊ฐ 3๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ๋
groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)โ
- ๊ทธ๋ฃนํ ๊ฒฐ๊ณผ๋ฅผ ํน์ ๋งต ํ์ ์ผ๋ก ์ ์ฅํด์ผ ํ ๋ (mapFactory)
- ๊ฐ ๊ทธ๋ฃน์ ๋ํด ๊ณ ์ ํ ์์ง ๋ฐฉ๋ฒ์ ์ง์ ํด์ผ ํ ๋ (downstream)
'Java > ๐ Effective Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๐ Effective Java] ์ผ๋ฐ์ ์ธ ํ๋ก๊ทธ๋๋ฐ ์์น ไธ (0) | 2024.11.19 |
---|---|
[๐Effective Java] ์ด๊ฑฐ ํ์ ๊ณผ ์ด๋ ธํ ์ด์ ไธ (1) | 2024.11.18 |
[๐ Effective Java] ์ ๋ค๋ฆญ ไธ (0) | 2024.10.12 |
[๐ Effective Java] ํด๋์ค์ ์ธํฐํ์ด์ค ไธ (1) | 2024.10.06 |
[๐ Effective Java] ํด๋์ค์ ์ธํฐํ์ด์ค ไธญ (2) | 2024.10.05 |
34. int ์์ ๋์ ์ด๊ฑฐ ํ์ ์ฌ์ฉํ๊ธฐ
์ด๊ฑฐ ํ์ = ์ผ์ ๊ฐ์์ ์์ ๊ฐ์ ์ ์ํ ๋ค์, ๊ทธ ์ธ์ ๊ฐ์ ํ์ฉํ์ง ์๋ ํ์
โด๏ธ ์ด๊ฑฐ ํจํด์ ๋จ์
- ํ์ ์์ ๋ณด์ฅ X
- ํํ๋ ฅ ์ข์ง X
- ํ๋ฒํ ์์๋ฅผ ๋์ดํ ๊ฒ์ด๋ผ ์์์ ๊ฐ์ด ๋ฐ๋๋ฉด ํด๋ผ์ด์ธํธ๋ ๋ฐ๋์ ๋ค์ ์ปดํ์ผํด์ผ ํจ
- ์ ์ ์์๋ ๋ฌธ์์ด๋ก ์ถ๋ ฅํ๊ธฐ ๊น๋ค๋ก์
๐ ์ด๊ฑฐ ํ์ (ENUM type)์ด ๋์
public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}
โณ๏ธ ์ด๊ฑฐ ํ์
- ์ด๊ฑฐ ํ์ ์์ฒด๋ ํด๋์ค
- ์์ ํ๋๋น ์์ ์ ์ธ์คํด์ค๋ฅผ ํ๋์ฉ ๋ง๋ค์ด public static final ํ๋๋ก ๊ณต๊ฐ
- ๋ฐ์์ ์ ๊ทผํ ์ ์๋ ์์ฑ์๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ์ฌ์ค์ final
- ํด๋ผ์ด์ธํธ๊ฐ ์ธ์คํด์ค๋ฅผ ์ง์ ์์ฑํ๊ฑฐ๋ ํ์ฅํ ์ ์์ผ๋ฏ๋ก ์ด๊ฑฐ ํ์
์ ์ธ์ผ๋ก ๋ง๋ค์ด์ง ์ธ์คํด์ค๋ค์ ๋ฑ ํ๋์ฉ๋ง ์กด์ฌ ๋ณด์ฅ
= ์ธ์คํด์ค ํต์ - ์ปดํ์ผํ์ ํ์ ์์ ์ฑ ์ ๊ณต
- ๊ฐ์์ ์ด๋ฆ ๊ณต๊ฐ์ด ์์ด์ ์ด๋ฆ์ด ๊ฐ์ ์์๋ ๊ณต์กด ๊ฐ๋ฅ
enum Color {
RED, GREEN, BLUE
}
enum Direction {
NORTH, SOUTH, EAST, WEST, RED
}
// Color.RED์ Direction.RED -> ๊ณต์กด ๊ฐ๋ฅ
- toString ๋ฉ์๋๋ก ๋ฌธ์์ด ์ถ๋ ฅ
- toString ๋ฉ์๋ ์ฌ์ ์ํ ์ toString์ด ๋ฐํํ๋ ๋ฌธ์์ด์ ํด๋น ์ด๊ฑฐ ํ์ ์์๋ก ๋ณํํด์ฃผ๋ fromString ๋ฉ์๋๋ ํจ๊ป ์ ๊ณตํ๊ธฐ !
- ์์์ ๋ฉ์๋๋ ํ๋ ์ถ๊ฐ ๊ฐ๋ฅ
- ์์์ ์ธํฐํ์ด์ค ๊ตฌํ ๊ฐ๋ฅ
// ๋ฐ์ดํฐ์ ๋ฉ์๋๋ฅผ ๊ฐ๋ ์ด๊ฑฐ ํ์
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7);
private final double mass; // ํ์ฑ์ ์ง๋ (ํฌ๋ก๊ทธ๋จ)
private final double radius; // ํ์ฑ์ ๋ฐ์ง๋ฆ (๋ฏธํฐ)
private final double surfaceGravity; // ํ์ฑ์ ํ๋ฉด ์ค๋ ฅ
// ์ค๋ ฅ ์์ (๋จ์: m^3 / kg s^2)
private static final double G = 6.67300E-11;
// ์ด๊ฑฐํ ์์ฑ์
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
this.surfaceGravity = G * mass / (radius * radius);
}
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
public double getSurfaceGravity() {
return surfaceGravity;
}
// ์ฃผ์ด์ง ์ง๋์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฑ์์์ ๋ฌด๊ฒ๋ฅผ ๊ณ์ฐ
public double surfaceWeight(double mass) {
return mass * surfaceGravity;
}
public static void main(String[] args) {
double earthWeight = 70.0; // ์์๋ก ์ง๊ตฌ์์ 70kg์ธ ์ฌ๋
double mass = earthWeight / Planet.EARTH.getSurfaceGravity();
for (Planet p : Planet.values()) {
System.out.printf("Weight on %s: %.2f N%n", p, p.surfaceWeight(mass));
}
}
}
๐ ์ด๊ฑฐ ํ์
์์ ๊ฐ๊ฐ์ ํน์ ๋ฐ์ดํฐ์ ์ฐ๊ฒฐ ์ง์ผ๋ ค๋ฉด ์์ฑ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ธ์คํด์ค ํ๋์ ์ ์ฅํ๋ฉด ๋จ
ํ๋๋ฅผ public์ผ๋ก ์ ์ธํด๋ ๋์ง๋ง, private์ผ๋ก ๋๊ณ ๋ณ๋์ public ์ ๊ทผ์ ๋ฉ์๋๋ฅผ ๋๋๊ฒ ๋์ ! (์์ดํ
16)
- ์ด๊ฑฐ ํ์ ์ ์์ ์์ ์ ์๋ ์์๋ค์ ๊ฐ์ ๋ฐฐ์ด์ ๋ด์ ๋ฐํํ๋ ์ ์ ๋ฉ์๋์ธ values ์ ๊ณต ๐ ๊ฐ๋ค์ ์ ์ธ๋ ์์๋ก ์ ์ฅ๋จ
โณ๏ธ ์์๋ณ ๋ฉ์๋ ๊ตฌํ์ ํ์ฉํ ์ด๊ฑฐ ํ์
public enum Operation {
ADD {public double apply(double x, double y) {return x + y;}},
SUBTRACT {public double apply(double x, double y) {return x - y;}},
MULTIPLY { public double apply(double x, double y) {return x * y;}},
DIVIDE {public double apply(double x, double y) {return x / y;}};
// ๊ฐ ์์๋ณ๋ก ๊ตฌํ๋ ์ถ์ ๋ฉ์๋
public abstract double apply(double x, double y);
}
- ๋จ์
- ์ด๊ฑฐ ํ์ ์์๋ผ๋ฆฌ ์ฝ๋ ๊ณต์ ์ด๋ ค์
enum PayrollDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
SATURDAY, SUNDAY;
private static final int MINS_PER_SHIFT = 8 * 60;
int pay(int minutesWorked, int payRate){
int basePay = minutesWorked * payRate;
int overtimePay;
switch(this){
case SATURDAY: case SUNDAY: // ์ฃผ๋ง -> ๋ฌด์กฐ๊ฑด ์์
์๋น์ด ์ฃผ์ด์ง
overtimePay = basePay/2;
break;
default: // ์ฃผ์ค -> ์ค๋ฒํ์ ๋ฐ์ ์ ์์
์๋น ์ฃผ์ด์ง
overtimePay = minutesWorked <= MINS_PER_SHIFT ?
0 : (minutesWorked - MINS_PER_SHIFT) * payRate / 2;
}
return basePay + overtimePay;
}
}
๐ ํด๊ฐ์ ๊ฐ์ ์๋ก์ด ๊ฐ์ ์ด๊ฑฐ ํ์ ์ ์ถ๊ฐํ๋ ค๋ฉด ๊ทธ ๊ฐ์ ์ฒ๋ฆฌํ๋ case๋ฌธ์ ์์ง ๋ง๊ณ ์์ผ๋ก ๋ฃ์ด์ค์ผ ํจใ ใ
โณ๏ธ ์ ๋ต ์ด๊ฑฐ ํ์ ํจํด
- ์์ ๊ฐ์ ์์์์ ์๋ก์ด ์์๋ฅผ ์ถ๊ฐํ ๋ ์์ ์๋น '์ ๋ต' ์ ํ
- ์์ ์๋น ๊ณ์ฐ์ private ์ค์ฒฉ ์ด๊ฑฐ ํ์ ์ผ๋ก ์ฎ๊ธฐ๊ณ , PayrollDay ์ด๊ฑฐ ํ์ ์ ์์ฑ์์์ ์ด์ค ์ ๋นํ ๊ฒ ์ ํ
- PayrollDay ์ด๊ฑฐ ํ์ ์ ์์ ์๋น ๊ณ์ฐ์ ๊ทธ ์ ๋ต ์ด๊ฑฐ ํ์ ์ ์์ํ์ฌ, switch ๋ฌธ์ด๋ ์์๋ณ ๋ฉ์๋ ๊ตฌํ์ด ํ์ X
enum PayrollDay{
MONDAY(WEEKDAY), TUESDAY(WEEKDAY), WEDNESDAY(WEEKDAY),
THURSDAY(WEEKDAY), FRIDAY(WEEKDAY), SATURDAY(WEEKEND), SUNDAY(WEEKEND);
private final PayType payType;
PayrollDay(PayType payType) {this.payType = payType;}
int pay(int minutesWorked, int payRate){
return payType.pay(minutesWorked, payRate);
}
// ์ ๋ต ์ด๊ฑฐ ํ์
enum PayType{
WEEKDAY{
int overtimePay(int minutesWorked, int payRate){
return minsWorked <= MINS_PER_SHIFT ? 0 :
(minsWorked - MINS_PER_SHIFT) * payRate / 2;
}
},
WEEKEND {
int overtimePay(int minutesWorked, int payRate){
return minsWorked * payRate / 2;
}
};
abstract int overtimePay(int mins, int payRate);
private static final int MINS_PER_SHIFT = 8 * 60;
int pay(int minsWorked, int payRate){
int basePay = minsWorked * payRate;
return basePay + overtimePay(minsWorked, payRate);
}
}
}
public class PayrollSystem {
public static void main(String[] args) {
// ๊ฐ ๋ ์ ๋ํด ๊ทผ๋ฌดํ ์๊ฐ๊ณผ ๊ธ์ฌ์จ์ ์ค์
int payRate = 10; // ๋ถ๋น ๊ธ์ฌ์จ (์: 10 ๋จ์)
// ๊ฐ ์์ผ์ ๋ํ ๊ทผ๋ฌด ์๊ฐ
int minutesWorkedMonday = 480; // 8์๊ฐ
int minutesWorkedSaturday = 600; // 10์๊ฐ
int minutesWorkedSunday = 120; // 2์๊ฐ
// ๊ธ์ฌ ๊ณ์ฐ
int mondayPay = PayrollDay.MONDAY.pay(minutesWorkedMonday, payRate);
int saturdayPay = PayrollDay.SATURDAY.pay(minutesWorkedSaturday, payRate);
int sundayPay = PayrollDay.SUNDAY.pay(minutesWorkedSunday, payRate);
// ๊ฒฐ๊ณผ ์ถ๋ ฅ
System.out.println("Monday Pay: $" + mondayPay); // ์ถ๋ ฅ: Monday Pay: $80
System.out.println("Saturday Pay: $" + saturdayPay); // ์ถ๋ ฅ: Saturday Pay: $50
System.out.println("Sunday Pay: $" + sundayPay); // ์ถ๋ ฅ: Sunday Pay: $20
}
}
โจ ๊ฒฐ๋ก ์ ์ผ๋ก, ์ด๊ฑฐ ํ์ ์ ์ธ์ ์จ์ผ ํ๋..?
๐ ํ์ํ ์์๋ฅผ ์ปดํ์ผ ํ์์ ๋ค ์ ์ ์๋ ์์ ์งํฉ์ด๋ผ๋ฉด ํญ์ ์ด๊ฑฐ ํ์ ์ฌ์ฉํ๊ธฐ !
์ด๊ฑฐ ํ์ ์ ์ ์๋ ์์ ๊ฐ์๊ฐ ์์ํ ๊ณ ์ ๋ถ๋ณ์ผ ํ์ X
35. ordinal ๋ฉ์๋ ๋์ ์ธ์คํด์ค ํ๋ ์ฌ์ฉํ๊ธฐ
๋๋ถ๋ถ์ ์ด๊ฑฐ ํ์ ์์๋ ํ๋์ ์ ์ซ๊ฐ์ ๋์ํ๋ฉฐ ํด๋น ์์๊ฐ ๊ทธ ์ด๊ฑฐ ํ์ ์์ ๋ช ๋ฒ์งธ ์์น์ธ์ง ๋ฐํํ๋ ordinal ๋ฉ์๋ ์ ๊ณต
๐ ์ ์ง๋ณด์ ๋ฐ ์ค์ฉ์ฑ์ด ๋จ์ด์ง
public enum Ensemble {
SOLO, DUET, TRIO, QUARTET, QUINTET,
SEXTET, SEPTET, OCTET, NONET, DECET;
public int numberOfMusicians() { return ordinal() + 1; }
}
ordinal ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ ๋ ๋จ์ ์ด ์๋ค.
- ์์ ์์์ ์์กด ๐ ์๋ก์ด ์์๋ฅผ ์ค๊ฐ์ ์ถ๊ฐํ๊ฑฐ๋ ์์๋ฅผ ๋ฐ๊พธ๋ฉด ๊ธฐ์กด์ ordinal ๊ฐ๋ ๋ฐ๋
- ์๋ฏธ ๋ถ์กฑ
- ์ค๊ฐ์ ๊ฐ์ ๋น์๋ ์ ์์
- ๊ฐ๋ ์ฑ ์ ํ
public enum Ensemble {
SOLO(1), DUET(2), TRIO(3), QUARTET,(4) QUINTET(5),
SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8), // ์ด๋ฏธ ์ฌ์ฉ์ค์ธ ์์๊ฐ ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ
NONET(9), DECET(10), TRIPLE_QUARTET(12); // ์ค๊ฐ์ ๊ฐ์ ๋น์ธ ์ ์์
private final int numberOfMusicians;
Ensemble(int size) { this.numberOfMusicians = size; }
public int numberOfMusicians() { return ordinal() + 1; }
}
36. ๋นํธ ํ๋ ๋์ EnumSet ์ฌ์ฉํ๊ธฐ
- ๋นํธ ํ๋ ์ฌ์ฉ ์ ๋นํธ๋ณ ์ฐ์ฐ์ ์ฌ์ฉํด ํฉ์งํฉ๊ณผ ๊ต์งํฉ ๊ฐ์ ์งํฉ ์ฐ์ฐ์ ํจ์จ์ ์ผ๋ก ์ํ ๊ฐ๋ฅ
- ์ ์ ์ด๊ฑฐ ์์์ ๋จ์ ์ ๊ทธ๋๋ก ์ง๋๋ฉฐ ํด์ํ๊ธฐ ์ด๋ ค์
- ์ต๋ ๋ช ๋นํธ๊ฐ ํ์ํ์ง๋ฅผ API ์์ฑ ์ ๋ฏธ๋ฆฌ ์์ธกํ์ฌ ์ ์ ํ ํ์ ์ ์ ํํด์ผ ํจ
public class Text{
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
public static final int STYLE_UNDERLINE = 1 << 2; // 4
public static final int STYLE_STRIKETHROUGH = 1 << 3; // 5
public void applyStyle(int styles){...}
}
โณ๏ธ EnumSet
- Set ์ธํฐํ์ด์ค ๊ตฌํ
- ํ์ ์์ ํ๊ณ ๋ค๋ฅธ ์ด๋ค Set ๊ตฌํ์ฒด์๋ ํจ๊ป ์ฌ์ฉ ๊ฐ๋ฅ
public class Text {
public enum Style {BOLD, ITALIC, UNDERLINE, STRIKETHROUGH}
// Set์ ๋๊น
public void applyStyles(Set<Style> styles) {...}
public static void main(String[] args) {
Text text = new Text();
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
}
}
- ์ applyStyles ๋ฉ์๋๋ EnumSet์ด ์๋ Set์ ๋ฐ์์๊น...
๐ ์ข ํน์ดํ ํด๋ผ์ด์ธํธ๊ฐ ๋ค๋ฅธ Set ๊ตฌํ์ฒด๋ฅผ ๋๊ธฐ๋๋ผ๋ ์ฒ๋ฆฌ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ !
37. ordinal ์ธ๋ฑ์ฑ ๋์ EnumMap ์ฌ์ฉํ๊ธฐ
class Plant {
enum LifeCycle {
ANNUAL, PERENNIAL, BIENNIAL // ํํด์ด์ด, ์ฌ๋ฌํด์ด์ด, ๋ํด์ด์ด
}
final String name;
final LifeCycle lifeCycle;
public Plant(String name, LifeCycle lifeCycle) {
this.name = name;
this.lifeCycle = lifeCycle;
}
@Override
public String toString() {
return name;
}
}
์ ์์ ์ฌ์ ์๋ฌผ๋ค์ ๋ฐฐ์ด ํ๋๋ก ๊ด๋ฆฌํ๊ณ , ์ด๋ค์ ์์ ์ฃผ๊ธฐ๋ณ๋ก ๋ฌถ์ ๋ ์ด 3๊ฐ์ ์งํฉ(ํํด, ์ฌ๋ฌํด, ๋ํด)์ ๋ง๋ค๊ณ ์ ์์ ์๋ ๊ฐ ์๋ฌผ์ ํด๋น ์งํฉ์ ๋ฃ์ผ๋ฉด ๋๋ค.
private void plantClassification(Plant[] garden) {
Map<Plant.LifeCycle, Set<Plant>> plantsByLifeCycle = new EnumMap<>(Plant.LifeCycle.class);
for (Plant.LifeCycle lc : Plant.LifeCycle.values()) {
plantsByLifeCycle.put(lc, new HashSet<>());
}
for (Plant p : garden) {
plantsByLifeCycle.get(p.lifeCycle).add(p);
}
System.out.println(plantsByLifeCycle);
}
// ์ถ๋ ฅ๊ฒฐ๊ณผ
// {ANNUAL=[Marigold, Sunflower], PERENNIAL=[Rose, Tulip], BIENNIAL=[Parsley]}
- ๋ด๋ถ์์ ๋ฐฐ์ด์ ์ฌ์ฉํ๊ณ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์์ ์์ผ๋ก ์จ๊ฒจ์ Map์ ํ์ ์์ ์ฑ๊ณผ ๋ฐฐ์ด์ ์ฑ๋ฅ์ ๋ชจ๋ ์ป์ด๋
- ๋งต์ ํค์ธ ์ด๊ฑฐ ํ์ ์ด ๊ทธ ์์ฒด๋ก ์ถ๋ ฅ์ฉ ๋ฌธ์์ด ์ ๊ณต
โณ๏ธ ์คํธ๋ฆผ์ ์ฌ์ฉํ ์ฝ๋ - EnumMap์ ์ด์ฉํด ๋ฐ์ดํฐ์ ์ด๊ฑฐ ํ์ ๋งคํ
System.out.println(Arrays.stream(garden)
.collect(groupingBy(p -> p.lifeCycle,
() -> new EnumMap<>(LifeCycle.class), toSet())));
- ๋ง์ฝ ํํด์ด์ด์ ์ฌ๋ฌํด์ด์ด ์๋ฌผ๋ง ์ด๊ณ ๋ํด์ด์ด๋ ์๋ค๋ฉด EnumMap ๋ฒ์ ์์๋ ๋งต์ 3๊ฐ ๋ง๋ค๊ณ , ์คํธ๋ฆผ ๋ฒ์ ์์๋ 2๊ฐ๋ง ๋ง๋ฆ
โณ๏ธ ordinal ๋ ๋ฒ ์ฐ๊ธฐ ...?
public enum Phase {
SOLID, LIQUID, GAS; //๊ณ ์ฒด, ์ก์ฒด, ๊ธฐ์ฒด
public enum Transition {
MELT, FREEZE, BOIL, CONDENSE, SUBLIME, DEPOSIT; // ์ตํด, ์๊ณ , ๊ธฐํ, ์๊ฒฐ, ์นํ, ์นํ
// ํ์ from์ ordinal์, ์ด์ to์ ordinal์ ์ธ๋ฑ์ค๋ก ์ฌ์ฉ
private static final Transition[][] TRANSITIONS = {
{ null, MELT, SUBLIME }, // ๊ณ ์ฒด๋ ์ตํด, ์นํ
{ FREEZE, null, BOIL }, // ์ก์ฒด๋ ์๊ณ , ๊ธฐํ
{ DEPOSIT, CONDENSE, null }, // ๊ธฐ์ฒด๋ ์นํ, ์๊ฒฐ
};
public static Transition from(Phase from, Phase to) {
return TRANSITIONS[from.ordinal()][to.ordinal()];
}
}
}
- Phase๋ Phase.Transition ์ด๊ฑฐ ํ์ ์ ์์ ํ๋ฉด์ ์์ ์ด ํ TRANSITIONS๋ฅผ ํจ๊ป ์์ ํ์ง ์๊ฑฐ๋ ์ค์๋ก ์๋ชป ์์ ํ๋ค๋ฉด ๋ฐํ์ ์ค๋ฅ ๋ฐ์
โณ๏ธ ์ค์ฒฉ EnumMap์ผ๋ก ๋ฐ์ดํฐ์ ์ด๊ฑฐ ํ์ ์์ ์ฐ๊ฒฐ
public enum Phase {
SOLID, LIQUID, GAS;
public enum Transition {
MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID),
BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID),
SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
private final Phase from;
private final Phase to;
Transition(Phase from, Phase to) {
this.from = from;
this.to = to;
}
// ์์ ์ด ๋งต ์ด๊ธฐํ
private static final Map<Phase, Map<Phase, Transition>> m =
Stream.of(values()).collect(groupingBy(t -> t.from,() -> new EnumMap<>(Phase.class),
toMap(t -> t.to, t -> t,
(x, y) -> y, () -> new EnumMap<>(Phase.class))));
public static Transition from(Phase from, Phase to) {
return m.get(from).get(to);
}
}
}
- ์์ชฝ ๋งต์ ์ด์ ์ํ์ ์ ์ด๋ฅผ ์ฐ๊ฒฐ
- ๋ฐ๊นฅ์ชฝ ๋งต์ ์ดํ ์ํ์ ์์ชฝ ๋งต ์ฐ๊ฒฐ
- groupingBy ๐ ์ ์ด๋ฅผ ์ด์ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฌถ์
- toMap ๐ ์ดํ ์ํ๋ฅผ ์ ์ด์ ๋์์ํค๋ EnumMap ์์ฑ
- (x, y) -> y๋ ์ ์ธ๋ง ํ๊ณ ์ค์ ๋ก๋ ์ฐ์ด์ง ์์
- Transition.from(Phase.SOLID, Phase.LIQUID)๋ฅผ ํธ์ถํ๋ฉด Transition.MELT๊ฐ ๋ฐํ
์์ ์ด ๋งต์ ์ด๊ธฐํํ๋ ์ฝ๋๋ ์ ๋ฒ ๋ณต์กํ์ง๋ง, ์๋ก์ด ์ํ์ธ PLASMA๋ฅผ ์ถ๊ฐํ๊ฒ ๋๋ค๋ฉด
์ํ๋ชฉ๋ก์ PLASMA๋ฅผ ์ถ๊ฐํ๊ณ , ์ ์ด ๋ชฉ๋ก์ IONIZE(GAS, PLASMA)์ DEIONIZE(PLASMA, GAS)๋ง ์ถ๊ฐํ๋ฉด ๋จ
โจ Collectors.groupingBy() ๋ฉ์๋๊ฐ 3๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ๋
groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)โ
- ๊ทธ๋ฃนํ ๊ฒฐ๊ณผ๋ฅผ ํน์ ๋งต ํ์ ์ผ๋ก ์ ์ฅํด์ผ ํ ๋ (mapFactory)
- ๊ฐ ๊ทธ๋ฃน์ ๋ํด ๊ณ ์ ํ ์์ง ๋ฐฉ๋ฒ์ ์ง์ ํด์ผ ํ ๋ (downstream)
'Java > ๐ Effective Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๐ Effective Java] ์ผ๋ฐ์ ์ธ ํ๋ก๊ทธ๋๋ฐ ์์น ไธ (0) | 2024.11.19 |
---|---|
[๐Effective Java] ์ด๊ฑฐ ํ์ ๊ณผ ์ด๋ ธํ ์ด์ ไธ (1) | 2024.11.18 |
[๐ Effective Java] ์ ๋ค๋ฆญ ไธ (0) | 2024.10.12 |
[๐ Effective Java] ํด๋์ค์ ์ธํฐํ์ด์ค ไธ (1) | 2024.10.06 |
[๐ Effective Java] ํด๋์ค์ ์ธํฐํ์ด์ค ไธญ (2) | 2024.10.05 |