Skip to content

Commit 899f810

Browse files
authored
Added Enum examples (#6)
1 parent 008cbc7 commit 899f810

File tree

3 files changed

+257
-0
lines changed

3 files changed

+257
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.stubbornjava.common;
2+
3+
import java.lang.reflect.Array;
4+
import java.util.EnumSet;
5+
import java.util.Map;
6+
import java.util.function.Function;
7+
8+
import com.google.common.collect.Maps;
9+
10+
// {{start:enumUtils}}
11+
public class EnumUtils {
12+
13+
public static <T, E extends Enum<E>> Function<T, E> lookupMap(Class<E> clazz, Function<E, T> mapper) {
14+
@SuppressWarnings("unchecked")
15+
E[] emptyArray = (E[]) Array.newInstance(clazz, 0);
16+
return lookupMap(EnumSet.allOf(clazz).toArray(emptyArray), mapper);
17+
}
18+
19+
public static <T, E extends Enum<E>> Function<T, E> lookupMap(E[] values, Function<E, T> mapper) {
20+
Map<T, E> index = Maps.newHashMapWithExpectedSize(values.length);
21+
for (E value : values) {
22+
index.put(mapper.apply(value), value);
23+
}
24+
return (T key) -> index.get(key);
25+
}
26+
}
27+
// {{end:enumUtils}}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.stubbornjava.common;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.util.function.Function;
6+
7+
import org.junit.Test;
8+
9+
public class EnumUtilsTest {
10+
11+
@Test
12+
public void testFromClass() {
13+
Function<String, EnumTest> nameLookup = EnumUtils.lookupMap(EnumTest.class, e -> e.getName());
14+
Function<Integer, EnumTest> numLookup = EnumUtils.lookupMap(EnumTest.class, e -> e.getNum());
15+
16+
for (EnumTest cur : EnumTest.values()) {
17+
assertEquals(cur, nameLookup.apply(cur.getName()));
18+
assertEquals(cur, numLookup.apply(cur.getNum()));
19+
}
20+
21+
// Extra sanity
22+
assertEquals(EnumTest.ZERO, nameLookup.apply("zero"));
23+
assertEquals(EnumTest.ZERO, numLookup.apply(0));
24+
}
25+
26+
@Test
27+
public void testFromValues() {
28+
Function<String, EnumTest> nameLookup = EnumUtils.lookupMap(EnumTest.values(), e -> e.getName());
29+
Function<Integer, EnumTest> numLookup = EnumUtils.lookupMap(EnumTest.values(), e -> e.getNum());
30+
31+
for (EnumTest cur : EnumTest.values()) {
32+
assertEquals(cur, nameLookup.apply(cur.getName()));
33+
assertEquals(cur, numLookup.apply(cur.getNum()));
34+
}
35+
36+
// Extra sanity
37+
assertEquals(EnumTest.ZERO, nameLookup.apply("zero"));
38+
assertEquals(EnumTest.ZERO, numLookup.apply(0));
39+
}
40+
41+
private enum EnumTest {
42+
ZERO("zero", 0),
43+
ONE("one", 1),
44+
TWO("two", 2),
45+
;
46+
private final String name;
47+
private final int num;
48+
private EnumTest(String name, int num) {
49+
this.name = name;
50+
this.num = num;
51+
}
52+
public String getName() {
53+
return name;
54+
}
55+
public int getNum() {
56+
return num;
57+
}
58+
}
59+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package com.stubbornjava.examples.common;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.function.Function;
7+
import java.util.stream.Collectors;
8+
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
12+
import com.fasterxml.jackson.annotation.JsonFormat;
13+
import com.google.common.base.Enums;
14+
import com.google.common.collect.Maps;
15+
import com.stubbornjava.common.EnumUtils;
16+
import com.stubbornjava.common.Json;
17+
18+
public class EnumLookup {
19+
private static final Logger log = LoggerFactory.getLogger(EnumLookup.class);
20+
21+
// {{start:enums}}
22+
public enum CardColor {
23+
RED,
24+
BLACK,
25+
;
26+
}
27+
28+
// Jackson annotation to print the enum as an Object instead of the default name.
29+
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
30+
public enum CardSuit {
31+
// Unicode suits - https://en.wikipedia.org/wiki/Playing_cards_in_Unicode
32+
SPADE("Spade", String.valueOf((char) 0x2660), CardColor.BLACK),
33+
HEART("HEART", String.valueOf((char) 0x2665), CardColor.RED),
34+
DIAMOND("Diamond", String.valueOf((char) 0x2666), CardColor.RED),
35+
CLUB("Club", String.valueOf((char) 0x2663), CardColor.BLACK),
36+
;
37+
38+
private String displayName;
39+
private String symbol;
40+
private CardColor color;
41+
private CardSuit(String displayName, String symbol, CardColor color) {
42+
this.displayName = displayName;
43+
this.symbol = symbol;
44+
this.color = color;
45+
}
46+
public String getDisplayName() {
47+
return displayName;
48+
}
49+
public void setDisplayName(String displayName) {
50+
this.displayName = displayName;
51+
}
52+
public String getSymbol() {
53+
return symbol;
54+
}
55+
public void setSymbol(String symbol) {
56+
this.symbol = symbol;
57+
}
58+
public CardColor getColor() {
59+
return color;
60+
}
61+
public void setColor(CardColor color) {
62+
this.color = color;
63+
}
64+
// {{end:enums}}
65+
66+
67+
// {{start:iteration}}
68+
/*
69+
* Please don't do this! It is inefficient and it's
70+
* not very hard to use Guava or a static Map as an index.
71+
*/
72+
public static CardSuit crappyFindByName(String name) {
73+
for (CardSuit suit : CardSuit.values()) {
74+
if (name.equals(suit.name())) {
75+
return suit;
76+
}
77+
}
78+
return null;
79+
}
80+
// {{end:iteration}}
81+
82+
// {{start:map}}
83+
private static final Map<String, CardSuit> nameIndex =
84+
Maps.newHashMapWithExpectedSize(CardSuit.values().length);
85+
static {
86+
for (CardSuit suit : CardSuit.values()) {
87+
nameIndex.put(suit.name(), suit);
88+
}
89+
}
90+
public static CardSuit lookupByName(String name) {
91+
return nameIndex.get(name);
92+
}
93+
// {{end:map}}
94+
95+
// {{start:guava}}
96+
public static CardSuit getIfPresent(String name) {
97+
return Enums.getIfPresent(CardSuit.class, name).orNull();
98+
}
99+
// {{end:guava}}
100+
101+
// {{start:mapDisplayName}}
102+
private static final Map<String, CardSuit> displayNameIndex =
103+
Maps.newHashMapWithExpectedSize(CardSuit.values().length);
104+
static {
105+
for (CardSuit suit : CardSuit.values()) {
106+
nameIndex.put(suit.getDisplayName(), suit);
107+
}
108+
}
109+
public static CardSuit lookupByDisplayName(String name) {
110+
return nameIndex.get(name);
111+
}
112+
// {{end:mapDisplayName}}
113+
114+
// {{start:mapDisplayNameUtil}}
115+
private static final Function<String, CardSuit> func =
116+
EnumUtils.lookupMap(CardSuit.class, e -> e.getDisplayName());
117+
public static CardSuit lookupByDisplayNameUtil(String name) {
118+
return func.apply(name);
119+
}
120+
// {{end:mapDisplayNameUtil}}
121+
}
122+
123+
// {{start:main}}
124+
public static void main(String[] args) {
125+
List<String> names = Arrays.stream(CardSuit.values())
126+
.map(e -> e.name())
127+
.collect(Collectors.toList());
128+
names.add("Missing");
129+
130+
List<String> displayNames = Arrays.stream(CardSuit.values())
131+
.map(e -> e.getDisplayName())
132+
.collect(Collectors.toList());
133+
displayNames.add("Missing");
134+
135+
136+
log.debug("Running valueOf");
137+
for (String name : names) {
138+
try {
139+
log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.valueOf(name)));
140+
} catch (Exception ex) {
141+
log.warn("Exception Thrown", ex);
142+
}
143+
}
144+
145+
log.debug("Running crappyFindByName");
146+
for (String name : names) {
147+
log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.crappyFindByName(name)));
148+
}
149+
150+
log.debug("Running lookupByName");
151+
for (String name : names) {
152+
log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.lookupByName(name)));
153+
}
154+
155+
log.debug("Running Guava getIfPresent");
156+
for (String name : names) {
157+
log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.getIfPresent(name)));
158+
}
159+
160+
log.debug("Running lookupByDisplayName");
161+
for (String displayName : displayNames) {
162+
log.debug("looking up {} found {}", displayName, Json.serializer().toString(CardSuit.lookupByDisplayName(displayName)));
163+
}
164+
165+
log.debug("Running lookupByDisplayNameUtil");
166+
for (String displayName : displayNames) {
167+
log.debug("looking up {} found {}", displayName, Json.serializer().toString(CardSuit.lookupByDisplayNameUtil(displayName)));
168+
}
169+
}
170+
// {{end:main}}
171+
}

0 commit comments

Comments
 (0)