Last active
October 26, 2023 15:34
-
-
Save chaotic3quilibrium/f70cc24e855ab18a2b13f557dbf356d3 to your computer and use it in GitHub Desktop.
Solution to Java Enum Generics Problem Posted on StackOverflow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.public_domain.enum_ops_plus_id; | |
public interface DbIdEnum<T> { | |
T getDbId(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.public_domain.enum_ops_plus_id; | |
import java.util.Collections; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.Objects; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
public final class DbIdEnumOps<E extends Enum<E> & DbIdEnum<T>, T> { | |
private final Map<T, E> enumValueByDbId; | |
private final Map<String, E> enumValueByNameLowerCaseOrDbId; | |
public static <E extends Enum<E> & DbIdEnum<T>, T> DbIdEnumOps<E, T> from(Class<E> enumClassE) { | |
return new DbIdEnumOps<>(enumClassE); | |
} | |
private DbIdEnumOps(Class<E> enumClassE) { | |
//how to validate AT COMPILE TIME `enumClassE` also conforms to `Class<EE>`? | |
var enumOpsList = | |
EnumOps.from(Objects.requireNonNull(enumClassE)) | |
.toList(); | |
this.enumValueByDbId = | |
Collections.unmodifiableMap( | |
enumOpsList | |
.stream() | |
.map(e -> Map.entry(e.getDbId(), e)) | |
.collect(Collectors.toMap(Entry::getKey, Entry::getValue))); | |
this.enumValueByNameLowerCaseOrDbId = | |
Collections.unmodifiableMap( | |
enumOpsList | |
.stream() | |
.flatMap(e -> Stream.of( | |
Map.entry(e.name().toLowerCase(), e), | |
Map.entry(e.getDbId().toString(), e))) | |
.collect(Collectors.toMap(Entry::getKey, Entry::getValue))); | |
} | |
public Map<T, E> getEnumValueByDbId() { | |
return this.enumValueByDbId; | |
} | |
public Map<String, E> getEnumValueByNameLowerCaseOrDbId() { | |
return this.enumValueByNameLowerCaseOrDbId; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.public_domain.enum_ops_plus_id; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.List; | |
public final class EnumOps<E extends Enum<E>> { | |
private final Class<E> enumClass; | |
private final List<E> enumsValues; | |
private EnumOps(Class<E> enumClass) { | |
this.enumClass = enumClass; | |
this.enumsValues = Collections.unmodifiableList(Arrays.asList(enumClass.getEnumConstants())); | |
} | |
public static <E extends Enum<E>> EnumOps<E> from(Class<E> enumClass) { | |
return new EnumOps<>(enumClass); | |
} | |
public Class<E> getEnumClass() { | |
return this.enumClass; | |
} | |
public List<E> toList() { | |
return this.enumsValues; | |
} | |
//omitted lots of other helpful enum utilities that ought to have been provided by the Java compiler by default | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.public_domain.enum_ops_plus_id; | |
public class Main { | |
public static void main(String[] args) { | |
var a = DbIdEnumOps.from(TrafficLight.class); | |
var b = DbIdEnumOps.<TrafficLight, Integer>from(TrafficLight.class); | |
DbIdEnumOps<TrafficLight, Integer> c = DbIdEnumOps.from(TrafficLight.class); | |
System.out.println("use me to set a breakpoint to examine the contents of the maps"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.public_domain.enum_ops_plus_id; | |
public enum TrafficLight implements DbIdEnum<Integer> { | |
GREEN(1), | |
YELLOW(2), | |
RED(3); | |
private final Integer dbId; | |
TrafficLight(Integer dbId) { | |
this.dbId = dbId; | |
} | |
private static final EnumOps<TrafficLight> enumOps = | |
EnumOps.from(TrafficLight.class); | |
private static final DbIdEnumOps<TrafficLight, Integer> dbIdEnumOpsA = | |
DbIdEnumOps.from(TrafficLight.class); | |
public static EnumOps<TrafficLight> ops() { | |
return enumOps; | |
} | |
public static DbIdEnumOps<TrafficLight, Integer> dbIdOps() { | |
return dbIdEnumOpsA; | |
} | |
public Integer getDbId() { | |
return this.dbId; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//StackOverflow Question: https://stackoverflow.com/q/77362860/501113 | |
//Updated/fixed the 5 code files to incorporate the answer by Turing85: https://stackoverflow.com/users/4216641/turing85 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment