Skip to content

Commit f5de36e

Browse files
author
Mark Putyato
committed
6: Use Enums instead of int constants
1 parent 6d5be4f commit f5de36e

File tree

5 files changed

+194
-0
lines changed

5 files changed

+194
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package by.morka.effective.java.enumsandannotations.useenumsinsteadofints;
2+
3+
// Switch on an enum to simulate a missing method
4+
public class Inverse {
5+
/**
6+
* Switch is applicable when:
7+
* 1. Enum is NOT UNDER OUR CONTROL
8+
* 2. ENUM is UNDER OUR CONTROL but the method ISN'T USEFUL ENOUGH TO BE IN ENUM
9+
*/
10+
public static Operation inverse(Operation op) {
11+
return switch (op) {
12+
case PLUS -> Operation.MINUS;
13+
case MINUS -> Operation.PLUS;
14+
case TIMES -> Operation.DIVIDE;
15+
case DIVIDE -> Operation.TIMES;
16+
};
17+
}
18+
19+
public static void main(String[] args) {
20+
double x = Double.parseDouble(args[0]);
21+
double y = Double.parseDouble(args[1]);
22+
for (Operation op : Operation.values()) {
23+
Operation invOp = inverse(op);
24+
System.out.printf("%f %s %f %s %f = %f%n",
25+
x, op, y, invOp, y, invOp.apply(op.apply(x, y), y));
26+
}
27+
}
28+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package by.morka.effective.java.enumsandannotations.useenumsinsteadofints;
2+
3+
import java.util.Map;
4+
import java.util.Optional;
5+
import java.util.stream.Stream;
6+
7+
import static java.util.stream.Collectors.toMap;
8+
9+
// Enum type with constant-specific class bodies and data
10+
public enum Operation {
11+
PLUS("+") {
12+
public double apply(double x, double y) { return x + y; }
13+
},
14+
MINUS("-") {
15+
public double apply(double x, double y) { return x - y; }
16+
},
17+
TIMES("*") {
18+
public double apply(double x, double y) { return x * y; }
19+
},
20+
DIVIDE("/") {
21+
public double apply(double x, double y) { return x / y; }
22+
};
23+
24+
private final String symbol;
25+
26+
Operation(String symbol) {
27+
// Can't access static member from constructor
28+
// stringToEnum;
29+
this.symbol = symbol;
30+
}
31+
32+
@Override public String toString() { return symbol; }
33+
34+
public abstract double apply(double x, double y);
35+
36+
// Implementing a fromString method on an enum type
37+
private static final Map<String, Operation> stringToEnum =
38+
Stream.of(values()).collect(
39+
toMap(Object::toString, e -> e));
40+
41+
// Returns Operation for string, if any
42+
public static Optional<Operation> fromString(String symbol) {
43+
return Optional.ofNullable(stringToEnum.get(symbol));
44+
}
45+
46+
public static void main(String[] args) {
47+
double x = Double.parseDouble(args[0]);
48+
double y = Double.parseDouble(args[1]);
49+
for (Operation op : Operation.values())
50+
System.out.printf("%f %s %f = %f%n",
51+
x, op, y, op.apply(x, y));
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package by.morka.effective.java.enumsandannotations.useenumsinsteadofints;
2+
3+
public enum PayrollDay {
4+
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
5+
SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND);
6+
7+
private final PayType payType;
8+
9+
PayrollDay(PayType payType) {
10+
this.payType = payType;
11+
}
12+
13+
PayrollDay() {
14+
this(PayType.WEEKDAY);
15+
}
16+
17+
public int pay(int minutesWorked, int payRate) {
18+
return this.payType.pay(minutesWorked, payRate);
19+
}
20+
21+
/**
22+
* Strategy enum
23+
* Useful when some constants share same behaviour
24+
*/
25+
private enum PayType {
26+
WEEKDAY {
27+
int overtimePay(int minsWorked, int payRate) {
28+
return minsWorked <= MINS_PER_SHIFT ? 0 :
29+
(minsWorked - MINS_PER_SHIFT) * payRate / 2;
30+
}
31+
},
32+
WEEKEND {
33+
int overtimePay(int minsWorked, int payRate) {
34+
return minsWorked * payRate / 2;
35+
}
36+
};
37+
38+
private static final int MINS_PER_SHIFT = 8 * 60;
39+
40+
abstract int overtimePay(int minutesWorked, int payRate);
41+
42+
public int pay(int minutesWorked, int payRate) {
43+
int basePay = minutesWorked * payRate;
44+
return basePay + overtimePay(minutesWorked, payRate);
45+
}
46+
}
47+
48+
public static void main(String[] args) {
49+
for (PayrollDay day : values())
50+
System.out.printf("%-10s%d%n", day, day.pay(8 * 60, 1));
51+
}
52+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package by.morka.effective.java.enumsandannotations.useenumsinsteadofints;
2+
3+
/**
4+
* 1. Final class
5+
* 2. Singleton
6+
* 3. Exports static final instance member
7+
*/
8+
public enum Planet {
9+
MERCURY(3.302e+23, 2.439e6),
10+
VENUS(4.869e+24, 6.052e6),
11+
EARTH(5.975e+24, 6.378e6),
12+
MARS(6.419e+23, 3.393e6),
13+
JUPITER(1.899e+27, 7.149e7),
14+
SATURN(5.685e+26, 6.027e7),
15+
URANUS(8.683e+25, 2.556e7),
16+
NEPTUNE(1.024e+26, 2.477e7);
17+
18+
private final double mass;
19+
private final double radius;
20+
private final double surfaceGravity;
21+
22+
private static final double G = 6.67300E-11;
23+
24+
Planet(double mass, double radius) {
25+
this.mass = mass;
26+
this.radius = radius;
27+
this.surfaceGravity = G * mass / (radius * radius);
28+
}
29+
30+
public double mass() {
31+
return mass;
32+
}
33+
34+
public double radius() {
35+
return radius;
36+
}
37+
38+
public double surfaceGravity() {
39+
return surfaceGravity;
40+
}
41+
42+
public double surfaceWeight(double mass) {
43+
return mass * surfaceGravity;
44+
}
45+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package by.morka.effective.java.enumsandannotations;
2+
3+
import by.morka.effective.java.enumsandannotations.useenumsinsteadofints.Planet;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class WeightTable {
7+
8+
@Test
9+
public void main() {
10+
double earthWeight = Double.parseDouble("76");
11+
double mass = earthWeight / Planet.EARTH.surfaceGravity();
12+
for (Planet p : Planet.values())
13+
System.out.printf("Weight on %s is %f%n",
14+
p, p.surfaceWeight(mass));
15+
}
16+
}

0 commit comments

Comments
 (0)