Most efficient way to sort and access final values - java

I have a class called "ClientFontRenderer" and I want to know the best way to store this. The method is being called every frame update which can be extremely quick so I'm not sure if I'm able to use arrays. What is the best way to store these variables in such a way that I can load them without a problem?
public class FontManager {
public static final FontManager INSTANCE;
private ClientFontRenderer LATOREGULAR, LATOSMALL, LATOBOLD;
private ClientFontRenderer SANSREGULAR, SANSBOLD, SANSITALIC;
public FontManager() {
}
public void initialize() {
LATOREGULAR = new ClientFontRenderer("Lato-Light", 16.0F);
LATOSMALL = new ClientFontRenderer("Lato-Light", 11.0F);
LATOBOLD = new ClientFontRenderer("Lato-Bold", 16.0F);
SANSREGULAR = new ClientFontRenderer("Sans-Regular", 16.0F);
}
public ClientFontRenderer loadFont(FontType type) {
switch(type) {
case LATO_REGULAR:
return LATOREGULAR;
case LATO_SMALL:
return LATOSMALL;
case LATO_BOLD:
return LATOBOLD;
case SANS_REGULAR:
return SANSREGULAR;
case SANS_BOLD:
return SANSBOLD;
case SANS_ITALIC:
return SANSITALIC;
default:
return LATOREGULAR;
}
}
static {
INSTANCE = new FontManager();
}
public enum FontType {
LATO_REGULAR,
LATO_SMALL,
LATO_BOLD,
SANS_REGULAR,
SANS_BOLD,
SANS_ITALIC
}

imo since you only used static initializers, you can make loadFont static as well
public class FontManager {
private static final EnumMap<FontType, ClientFontRenderer> fontMap = new EnumMap<>(FontType.class);
static {
fontMap.put(FontType.LATO_REGULAR, new ClientFontRenderer("Lato-Light", 16.0F);
...
}
public static ClientFontRenderer loadFont(FontType type) {
return fontMap.get(type);
}
public enum FontType {
LATO_REGULAR,
LATO_SMALL,
LATO_BOLD,
SANS_REGULAR,
SANS_BOLD,
SANS_ITALIC
}
)

Related

Java - how to call a method of corresponding class based on string using enum/factory pattern

Yes, I read many examples in web, but I didn't find a way how to call a method based on string value. May be I am not searching in right way... I wrote all code, but don't know how to call the method.
fyi: I don't want to use if else or switch case
Here is what I want:
I get the card reader type as String from database. I have to call the corresponding class' method.
My code:
LoginPanel.java
public class LoginPanel {
public static void main(String args[]) {
String readerType = "Omnikey5427-CK"; // I get this ("Omnikey5427-CK" or "Omnikey5427-G2") from a database as String
// I WANT TO CALL getCardNumber() method of respective class
}
}
ISmartCardReader.java
public interface ISmartCardReader {
public Integer getCardNumber();
}
Omnikey5427G2.java
public class Omnikey5427G2 implements ISmartCardReader {
public Omnikey5427G2() {
System.out.println("G222222222222222...");
}
public Integer getCardNumber() {
return 222;
}
}
Omnikey5427CK.java
public class Omnikey5427CK implements ISmartCardReader {
public Omnikey5427CK() {
System.out.println("CKKKKKKKKKKKKKKK...");
}
public Integer getCardNumber() {
return 111;
}
}
SmacrtCardEnumFactory.java
public enum SmacrtCardEnumFactory {
OMNIKEY5427CK("Omnikey5427-CK") {
public ISmartCardReader geInstance() {
return new Omnikey5427CK();
}
},
OMNIKEY5427G2("Omnikey5427-G2") {
public ISmartCardReader geInstance() {
return new Omnikey5427G2();
}
};
private String cardReaderName;
private SmacrtCardEnumFactory(String cardReaderName) {
this.cardReaderName = cardReaderName;
}
public String cardReaderName() {
return cardReaderName;
}
}
You can use valueOf() function of enum provided your enum sonstant names match strings used to lookup (you may use cardName.toUpper()). You may also create objects for all the card types and store them in a hash map and then lookup them. You can also write some fatory method, but this will be if-then-else or switch inside
You could iterate over the factory's values() and get the one that matches the string:
public enum SmacrtCardEnumFactory {
// current code omitted for brevity
public static getSmartCardReader(String name) {
return Arrays.stream(values())
.filter(r -> r.cardReaderName().equals(name))
.map(SmacrtCardEnumFactory::getInstance();
.orElse(null);
}
}

Using a fluent builder pattern without inner static classes for workflow

This is a continuation from what I was working in Passing 1 to many parameters of same object type
I've gotten good feedback on that , I believe i have the improved the design . The whole code is at https://github.com/spakai/flow_input_builder
The requirement is simple : -
I need to build a set of input for different workflows using 1 or more outputs from previous workflows
I have a set of interfaces
public interface SwfInput {
}
public interface SwfOutput {
}
public interface Workflow<I extends SwfInput, O extends SwfOutput> {
public O execute(I input);
}
public interface Builder<I extends SwfInput> {
public I build();
}
Now , Say I have 3 flows which gets executed in sequence FlowA->FlowB->FlowC
FlowC needs mandatory output from FlowB but only optionally from FlowA
so I have a implementation for FlowCBuilder
public class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowBOutput mandatoryflowBOutput;
private FlowAOutput optionalflowAOutput;
public FlowAOutput getOptionalflowAOutput() {
return optionalflowAOutput;
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
this.optionalflowAOutput = optionalflowAOutput;
return this;
}
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
this.mandatoryflowBOutput = mandatoryflowBOutput;
}
#Override
public FlowCInput build() {
FlowCInput input = new FlowCInput();
input.setMandatoryFromFlowB(mandatoryflowBOutput.getOutput1FromB());
if (optionalflowAOutput != null) {
input.setOptionalFromFlowA(optionalflowAOutput.getOutput2FromA());
}
return input;
}
}
one test i have written shows an example usage
FlowBOutput mandatoryflowBOutput = new FlowBOutput();
mandatoryflowBOutput.setOutput1FromB("iNeedThis");
FlowAOutput optionalflowAOutput = new FlowAOutput();
FlowCInput input = new FlowCInputBuilder(mandatoryflowBOutput)
.setOptionalflowAOutput(optionalflowAOutput)
.build();
I have not used static inner class for the Builder pattern.
Any suggestions are welcomed.
You should use static inner class. The key point of using this approach is that, the inner can directly access private properties of the object being constructed. This helps eliminating duplicated code since the builder does not need to maintain a long list of temporary state for the constructing. So, your code can be rewritten like this:
public class FlowCInput {
private int output1FromB; // suppose that it is int
private String output2FromA; // suppose that it is String
private FlowCInput() { }
//...
public static class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowCInput result;
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
result = new FlowCInput();
// output1FromB is private but still accessed from here
result.output1FromB = mandatoryflowBOutput.getOutput1FromB();
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
// same for output2FromA
result.output2FromA = optionalflowAOutput.getOutput2FromA();
return this;
}
#Override
public FlowCInput build() {
return result;
}
}
}
As you see, the builder now holds only a FlowCInput object, it does not unnecessarily hold mandatoryflowBOutput and optionalflowAOutput as before.

Using enum to choose internal implementation

Task: have a class that implements something in different ways. User of class should only see public enum that represents available options, while hiding all implementation of different behavior.
To avoid checking the provided "style" on every call of method, constructor uses switch on enum value provided to assign appropriate inner private class to a field.
Here is SSCCE:
public class Greeter {
public enum GreetingStyle { HEY, HELLO }
private String name;
private GreetingChooser greetingChooser;
public Greeter(String name, GreetingStyle style) {
this.name = name;
switch(style) {
case HEY:
greetingChooser = new Hey();
break;
case HELLO:
greetingChooser = new Hello();
break;
default :
throw new UnsupportedOperationException("GreetingStyle value not handled : " + style.toString());
}
}
public void greet() {
// need to avoid switch(style) here
System.out.println(greetingChooser.greeting() + ", " + name + "!");
}
// this interface can't be public
private interface GreetingChooser {
String greeting();
}
private class Hey implements GreetingChooser {
public String greeting() {
return "Hey";
}
}
private class Hello implements GreetingChooser {
public String greeting() {
return "Hello";
}
}
public static void main(String args[]) {
new Greeter("John Doe", Greeter.GreetingStyle.HEY).greet();
new Greeter("John Doe", Greeter.GreetingStyle.HELLO).greet();
}
}
Question: is it a good way to implement such a functionality to make it maintainable in the future (e.g. we'll need to add GreetingStyle ALOHA)? Another idea I had was to use a static map
private static final Map<GreetingStyle, GreetingChooser> greetingMap;
static {
greetingMap = new HashMap<>();
greetingMap.put(Greeter.GreetingStyle.HEY, new Hey());
greetingMap.put(Greeter.GreetingStyle.HELLO, new Hello());
}
and to use greetingMap.get(style) in constructor.
Note: in Java 8 it would be probably best implemented with lambdas (if interface only has one function), but I'm constrained to Java 7.
Instead of just using the enum as a constant for the factory switch, you could avoid the switch by equipping the enum constant with either configuration
public enum GreetingStyle
{
HEY("Hey"),
HELLO("Hello");
GreetingStyle(String text) {
this.text = text;
}
public final String text;
}
or behaviour:
public enum GreetingStyle
{
HEY {
public void greet() { /* performs hey style greeting*/ }
},
HELLO{
public void greet() { /* performs hello style greeting*/ }
};
public abstract void greet();
}
Why are you bound to the enum? What you describe can be easily achieved using polymorphism. If you worry about extending it in the future, you can use design patterns such as Factory or Decorator.

Using wild cards with static classes in java

The idea I'm going for is that I have a bunch of actions/functions that happen in our program. They're all predefined and separated into categories. So there might be a category for admin actions that then defines a bunch of static codes for actions that are in the admin actions category.
Since the categories and actions are fixed, they're all in static classes.
These static category classes all implement an interface, ICategory:
public static interface ICategory{
int getCateogory();
String getCategoryName();
String getFunctionName(int function);
}
Each of these static classes is added to a static Map:
private static Map<Integer, Class<? extends ICategory>> catMap = new HashMap<Integer, Class<? extends ICategory>>();
Basically there's an integer code associated with each category. What I'm trying to do is just made a human readable string that I can print out when I receive the category and action codes. What I would like to do is something like
ICategory whatever = catMap.get(catNumber);
System.out.println(whatever.getCategoryName());
System.out.println(whatever.getFunctionName(actionCode));
So catMap.get(catNumber) will actually return the proper static class, but I then don't know how I can use that returned class to access these static methods. I can do it with regular instances of a class, just fine, but doing it with static classes has got me puzzled.
Clarification of Problem:
Some Clarification of The problem I'm trying to solve in case you guys have suggestions of better / more intuitive ways to do this:
Basically I'm interpreting commands from some piece of custom hardware at my company. It's a little data collection gizmo that has a bunch of predefined messages/functions that I have to interpret.
These functions are split into various categories: Display, Keypad, Acquisition, etc.
So basically I have a mapping like this:
Display Category: 128
ShowGraph: 01
ShowText: 02
Keypad Category: 129
F1: 01
F2: 02
MenuKey: 03
I'm making a little stream display that prints the stream of commands out in human readable format. So I'd just print out a big list of something like
Got Category Display, Function ShowGraph
Got Category Keypad, Function MenuKey
Normally I'd use a map for this, but what I want is to also use the functions in each category as constants because I'll have to reference them in if-statements and often times send those same categories back to the little gizmo.
For Instance:
sendMessage(Categories.DisplayCategory.getCategoryInt(), Categories.DisplayCategory.SHOW_GRAPH);
More Code as requested:
public class Functions {
public static interface ICategory{
int getCateogory();
String getCategoryName();
String getFunctionName(int function);
}
private static Map<Integer, Class<? extends ICategory>> catMap = new HashMap<Integer, Class<? extends ICategory>>();
public static String getCategoryString(int category) {
Class<? extends ICategory> clazz = catMap.get(category);
System.out.println(catMap.toString());
if(clazz != null){
try{
Method m = clazz.getMethod("getCategoryName", Integer.class);
return (String) m.invoke(0, category);
}catch (Exception e){
return null;
}
}else{
System.out.println("clazz was null");
return null;
}
}
public static class SystemKey implements ICategory{
public static int CATEGORY = 134;
private static Map<Integer, String> fmap = new HashMap<Integer, String>();
#Override
public int getCateogory() {
return CATEGORY;
}
#Override
public String getCategoryName() {
return "SystemKey";
}
#Override
public String getFunctionName(int function) {
return fmap.get(function);
}
}
public static class SystemCat implements ICategory{
public static int CATEGORY = 128;
private static Map<Integer, String> fmap = new HashMap<Integer, String>();
public static final int POWER_UP = 0x01;
public static final int END_OF_TRANSMIT = 0x02;
public static final int CLEAR_TO_SEND = 0x03;
public static final int NET_TEST = 0x05; /*Fom station to ctrlr*/
public static final int NET_OK = 0x06; /*Response to controller*/
public static final int MAIN_MENU = 0x07;
static{
catMap.put(CATEGORY, SystemCat.class);
fmap.put(POWER_UP, "POWER_UP");
fmap.put(END_OF_TRANSMIT, "END_OF_TRANSMIT");
fmap.put(CLEAR_TO_SEND, "CLEAR_TO_SEND");
fmap.put(NET_TEST, "NET_TEST");
fmap.put(NET_OK, "NET_OK");
fmap.put(MAIN_MENU, "MAIN_MENU");
}
#Override
public int getCateogory() {
return CATEGORY;
}
#Override
public String getCategoryName() {
return "System";
}
#Override
public String getFunctionName(int function) {
return fmap.get(function);
}
}
public static class SoftKey implements ICategory{
public static int CATEGORY = 129;
private static Map<Integer, String> fmap = new HashMap<Integer, String>();
public static final int F1 = 0x20;
public static final int F2 = 0x21;
public static final int F3 = 0x22;
public static final int F4 = 0x23;
public static final int F5 = 0x24;
static{
catMap.put(CATEGORY, SoftKey.class);
fmap.put(F1, "F1");
fmap.put(F2, "F2");
fmap.put(F3, "F3");
fmap.put(F4, "F4");
fmap.put(F5, "F5");
#Override
public int getCateogory() {
return CATEGORY;
}
#Override
public String getCategoryName() {
return "SoftKey";
}
#Override
public String getFunctionName(int function) {
return fmap.get(function);
}
}
public static void main (String[] args) throws Exception{
System.out.println(Functions.getCategoryString(128));
}
}
Update
As I suspected, the solution is quite simple. There are different ways to do this, here is one, I seem to remember calling it Registry, back in the days when Patterns were known as Idioms. You are almost there, what you need is following changes:
Change catMap type from Map<String,Class<? extends ICategory> to Map<Integer, ICategory>.
In the static initializers create an object and put it in the map, e.g.
public static class SoftKey implements ICategory{
....
static{
catMap.put(CATEGORY, new SoftKey());
In getCategoryString use the ICategory object in the registry:
ICategory categ = catMap.get(category);
return categ.getCategoyString()
I might have misunderstood the question, but part of it are confusing:
So catMap.get(catNumber) will actually return the proper static class,
By static class I assume you mean that the interfaces are nested inside some class/interface. There is no such thing as a top-level static class in Java. get returns an Object of a static class, not a class.
but I then don't know how I can use that returned class to access these static methods.
The methods you have declared are not static, they are instance methods
I can do it with regular instances of a class, just fine, but doing it with static classes has got me puzzled.
I am puzzled too. You can call instance methods on objects of static class. Can you post a complete code sample?
Assuming you know all the codes in advance, and there aren't 1000s of function values, this would work. The non-uniqueness of the function value codes isn't a problem as long as you don't mind looking through a container to find them (as opposed to a Map).
You could do away with the static maps completely if you don't mind looping through all the enum values all the time. This could be perfectly acceptable if you don't do lookups very often.
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public enum FunctionCategory {
DISPLAY(128, "Display"),
KEYPAD(129, "KeyPad");
// more categories here...
private final int code;
private final String name;
private static Map<Integer, FunctionCategory> categoryMap = new HashMap<>();
static {
for( FunctionCategory c : FunctionCategory.values() ) {
categoryMap.put(c.getCode(), c);
}
}
// For looking up a category from its code
public static FunctionCategory fromCode( int code ) {
return categoryMap.get(code);
}
private FunctionCategory(int code, String name) {
this.code = code;
this.name = name;
}
public int getCode() {
return code;
}
public String getName() {
return name;
}
public static enum FunctionValue {
// DISPLAY
DISPLAY_GRAPH(DISPLAY, 1, "Graph"),
DISPLAY_TEXT(DISPLAY, 2, "ShowText"),
//KEYPAD
KEYPAD_MENU(KEYPAD, 1, "MenuKey"),
KEYPAD_ENTER(KEYPAD, 2, "EnterKey");
// TODO, others
private static Map<FunctionCategory, Set<FunctionValue>> codeMapping = new EnumMap<>( FunctionCategory.class );
static {
for( FunctionValue fv : FunctionValue.values() ) {
Set<FunctionValue> values = codeMapping.get(fv.getCategory());
if( values == null ) {
values = EnumSet.of(fv);
}
else {
values.add(fv);
}
codeMapping.put(fv.getCategory(), values);
}
}
// First we look up the category, then we just loop over all the values
// within that category. Unless you have lots of values, or really need
// to optimize the lookups, there is no need to do something more complex
public static FunctionValue getFromCodes( int categoryCode, int valueCode ) {
FunctionCategory c = FunctionCategory.fromCode(categoryCode);
if( c != null ) {
Set<FunctionValue> valueSet = codeMapping.get(c);
if( valueSet != null ) {
// Just spin through them, there aren't that many
for( FunctionValue v : valueSet ) {
if( v.getCode() == valueCode ) {
return v;
}
}
}
}
return null;
}
private final FunctionCategory category;
private final int code;
private final String name;
private FunctionValue(FunctionCategory category, int code, String name) {
this.category = category;
this.code = code;
this.name = name;
}
public FunctionCategory getCategory() {
return category;
}
public int getCode() {
return code;
}
public String getName() {
return name;
}
}
}

java - an enum question

I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx

Categories