1+ package effectivejava ;
2+
3+ import java .util .EnumMap ;
4+ import java .util .HashMap ;
5+ import java .util .Map ;
6+
7+ /**
8+ * Created by zhangbin on 16/2/3.
9+ */
10+ public class Favorites {
11+ private Map <Class <?>, Object > favorites = new HashMap <>();
12+
13+ public <T > void putFavorite (Class <T > type , T instance ) {
14+ if (type == null ) {
15+ throw new NullPointerException ("Type is null" );
16+ }
17+ favorites .put (type , type .cast (instance ));
18+ }
19+
20+ public <T > T getFavorite (Class <T > type ) {
21+ return type .cast (favorites .get (type ));
22+ }
23+ }
24+
25+ enum Planet {
26+ MERCURY (3.302e+23 , 2.439e6 ),
27+ VENUS (4.869e+24 , 6.052e6 ),
28+ EARTH (5.975e+24 , 6.378e6 ),
29+ MARS (6.419e+23 , 3.393e6 ),
30+ JUPITER (1.899e+27 , 7.149e7 ),
31+ SATURN (5.685e+26 , 6.027e7 ),
32+ URANUS (8.683e+25 , 2.556e7 ),
33+ NEPTUNE (1.024e+26 , 2.477e7 );
34+ private final double mass ;
35+ private final double radius ;
36+ private final double surfaceGravity ;
37+
38+ private static final double G = 6.67300E-11 ;
39+
40+ Planet (double mass , double radius ) {
41+ this .mass = mass ;
42+ this .radius = radius ;
43+ surfaceGravity = G * mass / (radius * radius );
44+ }
45+
46+ public double mass () {
47+ return mass ;
48+ }
49+
50+ public double radius () {
51+ return radius ;
52+ }
53+
54+ public double surfaceWeight (double mass ) {
55+ return mass * surfaceGravity ;
56+ }
57+
58+ public double surfaceGravity () {
59+ return surfaceGravity ;
60+ }
61+ }
62+
63+ class WeightTable {
64+ public static void main (String [] args ) {
65+ double earthWeight = Double .parseDouble (args [0 ]);
66+ double mass = earthWeight / Planet .EARTH .surfaceGravity ();
67+ for (Planet p : Planet .values ()) {
68+ System .out .printf ("Weight on %s is %f%n" , p , p .surfaceWeight (mass ));
69+ }
70+ double num = Operation .DIVIDE .apply (10 , 20 );
71+ System .out .println (num );
72+ }
73+ }
74+
75+ enum Operation {
76+ PLUS {
77+ double apply (double x , double y ) {
78+ return x + y ;
79+ }
80+ },
81+ MINUS {
82+ double apply (double x , double y ) {
83+ return x - y ;
84+ }
85+ },
86+ TIMES {
87+ double apply (double x , double y ) {
88+ return x * y ;
89+ }
90+ },
91+ DIVIDE {
92+ double apply (double x , double y ) {
93+ return x / y ;
94+ }
95+ };
96+
97+ abstract double apply (double x , double y );
98+ }
99+
100+ enum Operations {
101+ PLUS ("+" ) {
102+ double apply (double x , double y ) {
103+ return x + y ;
104+ }
105+ },
106+ MINUS ("-" ) {
107+ double apply (double x , double y ) {
108+ return x - y ;
109+ }
110+ },
111+ TIMES ("*" ) {
112+ double apply (double x , double y ) {
113+ return x * y ;
114+ }
115+ },
116+ DIVIDE ("/" ) {
117+ double apply (double x , double y ) {
118+ return x / y ;
119+ }
120+ };
121+
122+ private final String symbol ;
123+
124+ Operations (String symbol ) {
125+ this .symbol = symbol ;
126+ }
127+
128+ @ Override
129+ public String toString () {
130+ return symbol ;
131+ }
132+
133+ abstract double apply (double x , double y );
134+
135+ public static void main (String [] args ) {
136+ double x = Double .parseDouble (args [0 ]);
137+ double y = Double .parseDouble (args [1 ]);
138+ for (Operation op : Operation .values ()) {
139+ System .out .printf ("%f %s %f = %f%n" , x , op , y , op .apply (x , y ));
140+ }
141+ }
142+ }
143+
144+ enum PayrollDay {
145+ MONDAY , TUESDAY , WEDNESDAY , THURSDAY , FRIDAY , SATURDAY , SUNDAY ;
146+ private static final int HOURS_PER_SHIFT = 8 ;
147+
148+ double pay (double hoursWorked , double payRate ) {
149+ double basePay = hoursWorked * payRate ;
150+ double overtimePay ;
151+ switch (this ) {
152+ case SATURDAY :
153+ case SUNDAY :
154+ overtimePay = hoursWorked * payRate / 2 ;
155+ break ;
156+ default :
157+ overtimePay = hoursWorked <= HOURS_PER_SHIFT ? 0 : (hoursWorked - HOURS_PER_SHIFT ) * payRate / 2 ;
158+ break ;
159+ }
160+ return basePay + overtimePay ;
161+ }
162+ }
163+
164+ enum PayrollDay2 {
165+ MONDAY (PayType .WEEKDAY ), TUESDAY (PayType .WEEKDAY ),
166+ WEDNESDAY (PayType .WEEKDAY ), THURSDAY (PayType .WEEKDAY ),
167+ FRIDAY (PayType .WEEKDAY ),
168+ SATURDAY (PayType .WEEKEND ), SUNDAY (PayType .WEEKEND );
169+
170+ private static final int HOURS_PER_SHIFT = 8 ;
171+
172+
173+ private final PayType payType ;
174+
175+ PayrollDay2 (PayType payType ) {
176+ this .payType = payType ;
177+ }
178+
179+ double pay (double hoursWorked , double payRate ) {
180+ return payType .pay (hoursWorked , payRate );
181+ }
182+
183+ private enum PayType {
184+ WEEKDAY {
185+ double overtimePay (double hours , double payRate ) {
186+ return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT ) * payRate / 2 ;
187+ }
188+ },
189+ WEEKEND {
190+ double overtimePay (double hours , double payRate ) {
191+ return hours * payRate / 2 ;
192+ }
193+ };
194+
195+ abstract double overtimePay (double hours , double payRate );
196+
197+ double pay (double hoursWorked , double payRate ) {
198+ double basePay = hoursWorked * payRate ;
199+ return basePay + overtimePay (hoursWorked , payRate );
200+ }
201+ }
202+ }
203+
204+ interface Operation1 {
205+ double apply (double x , double y );
206+ }
207+
208+ enum ExtendedOperation implements Operation1 {
209+ EXP ("^" ) {
210+ public double apply (double x , double y ) {
211+ return Math .pow (x , y );
212+ }
213+ },
214+ REMAINDER ("%" ) {
215+ public double apply (double x , double y ) {
216+ return x % y ;
217+ }
218+ };
219+ private final String symbol ;
220+
221+ ExtendedOperation (String symbol ) {
222+ this .symbol = symbol ;
223+ }
224+
225+ @ Override
226+ public String toString () {
227+ return symbol ;
228+ }
229+
230+ public static void main (String [] args ) {
231+ double x = Double .parseDouble (args [0 ]);
232+ double y = Double .parseDouble (args [1 ]);
233+ test (ExtendedOperation .class , x , y );
234+ }
235+
236+ private static <T extends Enum <T > & Operation1 > void test (Class <T > opSet , double x , double y ) {
237+ for (Operation1 op : opSet .getEnumConstants ()) {
238+ System .out .printf ("%f %s %f = %f%n" , x , op , y , op .apply (x , y ));
239+ }
240+ }
241+ }
242+
243+ enum Phase {
244+ SOLID , LIQUID , GAS ;
245+
246+ public enum Transition {
247+ MELT (SOLID , LIQUID ), FREEZE (LIQUID , SOLID ),
248+ BOIL (LIQUID , GAS ), CONDENSE (GAS , LIQUID ),
249+ SUBLIME (SOLID , GAS ), DEPOSIT (GAS , SOLID );
250+
251+ private final Phase src ;
252+ private final Phase dst ;
253+
254+ Transition (Phase src , Phase dst ) {
255+ this .src = src ;
256+ this .dst = dst ;
257+ }
258+
259+ private static final Map <Phase , Map <Phase , Transition >> m = new EnumMap <>(Phase .class );
260+
261+ static {
262+ for (Phase p : Phase .values ()) {
263+ m .put (p , new EnumMap <>(Phase .class ));
264+ }
265+ for (Transition trans : Transition .values ()) {
266+ m .get (trans .src ).put (trans .dst , trans );
267+ }
268+ }
269+
270+ public static Transition from (Phase src , Phase dst ) {
271+ return m .get (src ).get (dst );
272+ }
273+ }
274+ }
0 commit comments