Java Enum with multiple datatype fields? - java

I have following fields
a(String)
b(String)
c(String)
d(boolean)
e(boolean)
Is it possible to have them all in an Enum like following?
public enum Fields {
a("A")
b("B")
c("C")
d(true)
e(false)
}

You can have them but you should define constructors which takes String or boolean as parameters.
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
CONSTANT_FLAG1(false);
CONSTANT_FLAG2(true);
private String constants;
private boolean flag;
private Constants(String cons) {
this.constants = cons;
}
private Constants(boolean lFlag) {
this.flag= lFlag;
}
}

It sounds like you are using an enum to store constants, which is bad practice.

It is possible, but I would advice against it. In most cases, what you really want is a common interface, which is implemented by two (or more) different classes.
Please also note that is fully legitimate for an enum to implement an interface, but it is seldom you see two enums implement the same interface like in the example below:
public interface Fields {
}
public enum StringFields implements Fields {
A("A"),
B("B"),
C("C")
private StringFields(String str) {
this.str = str;
}
private final String str;
}
public enum BooleanFields implements Fields {
D(true),
E(false);
private BooleanFields(boolean val) {
this.val = val;
}
private final boolean val;
}

You can have two different constructors in the enum, but that means you need to have two fields (with one of them not being set). I do not think this would make much sense.
public enum Fields {
a("A"), b("B"), c("C"), d(true), e(false);
Fields(String str) {
strval = str;
value = false;
}
Fields(boolean val) {
strval = null;
value = val;
}
private final String strval;
private final boolean value;
}
EDITED*** Compiles now. You have to initialize both at the same time.

Related

How to use enums to define constant value groups

im using interface to accesses the project constant
this is my interface
public interface ConstantValues {
interface PaymentType {
public static final String CREDIT_CUSTOMER = "credit";
public static final String CASH_CUSTOMER = "cash";
}
interface PaymentMethode {
public static final String CREDIT_CARD = "creditcard";
public static final String VISA_CARD = "visacard";
public static final String MASTER_CARD = "mastercard";
}
}
im accessing this values form the java class like in the below
ConstantValues.PaymentType.CREDIT_CUSTOMER
or
ConstantValues.PaymentType.VISA_CARD
but i want to know how to do this using enum, because using a
interfaces to define constant is bad practice can please anybody
tell me how to do that using enum and how to access it from java class?
Here you go:
enum PaymentType {
CREDIT_CUSTOMER,
CASH_CUSTOMER;
}
enum PaymentMethod {
CREDIT_CARD,
VISA_CARD,
MASTER_CARD;
}
Use it like:
PaymentMethod meth = PaymentMethod.VISA_CARD;
etc.
public class Enums {
public enum Test {
FIRST,
SECOND,
THIRD
}
public enum Test2 {
FIRST("first"),
SECOND("second"),
THIRD("third");
private final String value;
Test2(String value) {
this.value = value;
}
}
public static void main(String[] args) {
System.out.println(Enums.Test.FIRST);
System.out.println(Enums.Test2.FIRST.value);
}
}

Declare constants inside of enum

I want to create an enum and declare several constants inside of it for inner usage...
public enum SearchType {
static final String TEXT = "text";
static final String BOOLEAN = "boolean";
STARTS_WITH(TEXT),
ENDS_WITH(TEXT),
CONTAINS(BOOLEAN),
WILDCARD(TEXT),
REGEXP(TEXT),
RANGE(TEXT)
private String searchType;
private SearchType(String type) {
searchType = type;
}
}
unfortunately it can't be done this way. Best solution I've come up with so far is to declare a nested interface to store constants...
public enum SearchType {
STARTS_WITH(Categories.TEXT),
ENDS_WITH(Categories.TEXT),
CONTAINS(Categories.BOOLEAN),
WILDCARD(Categories.TEXT),
REGEXP(Categories.TEXT),
RANGE(Categories.TEXT)
interface Categories{
static final String TEXT = "text";
static final String BOOLEAN = "boolean";
}
private String searchType;
private SearchType(String type) {
searchType = type;
}
}
so I'm wondering if there is a better way to do so?
I would use an enum for the Categories as well. If you place this in a top level class, it will look natural.
You have to define your enum values before any other constants.
AFAIK This is done to simplify the syntax. You have the enum values first with a special, simplified syntax, followed by the constants you define. The need for this is more obvious when you start overriding methods in your constants.

How to declare field inside Enum in Java?

I want to declare static(or not static) variable inside Enum. I need this because I want to associate enum values with some strings. But i Don't want to hardcode this strings. I want to use my application-wide class with String constants.
I.e. I want to write like this inside enum declaraton, but there compile time error:
public enum MyEnum {
private static final AppConstants CONSTANTS = AppConstants.getInstance();
ONE(CONSTANTS.one()),
TWO(CONSTANTS.two());
}
How I can put in enum a field?
It's one of the limitations, the enum values must be specified first but you can always refer to the same singelton in every instantiation...
enum MyEnum {
ONE(Test.getInstance().one()),
TWO(Test.getInstance().two());
public final String val;
MyEnum(String val) { this.val = val; }
}
Example that outputs "hello":
public class Test {
public static void main(String[] args) {
System.out.println(MyEnum.ONE.val);
}
public String one() {
return "hello";
}
public String two() {
return "world" ;
}
static Test instance;
public synchronized static Test getInstance() {
if (instance == null)
instance = new Test();
return instance;
}
}
It's a bit hacky. But you'll have to change your AppConstants class a bit.
public enum MyEnum {
ONE(getConstant("one")),
TWO(getConstant("one"));
private static final AppConstants CONSTANTS = AppConstants.getInstance();
private static String getConstant(String key) {
// You can use a map inside the AppConstants or you can
// invoke the right method using reflection. Up to you.
return CONSTANTS.get(key);
}
private MyEnum(String value) {
}
}
The enum constants need to be the first elements in the Enumeration
public enum MyEnum {
ONE,TWO;
private static final AppConstants CONSTANTS = AppConstants.getInstance();
#Override
public String toString() {
if(this==ONE){
return CONSTANTS.one();
} else if(this==TWO){
return CONSTANTS.two();
}
return null;
}
}

Enforcing dynamic polymorphic calls with general parent type input arguments

I am trying to use polymorphism to enable different processing of an object based on its class, as follows:
public class GeneralStuff {
private int ID;
}
public class IntStuff extends GeneralStuff {
private int value;
public void setValue(int v)
{
value = v;
}
public int getValue()
{
return value;
}
}
public class DoubleStuff extends GeneralStuff {
private double value;
public void setValue(double v)
{
value = v;
}
public double getValue()
{
return value;
}
}
public class ProcessStuff {
public String process(GeneralStuff gS)
{
return doProcess(gS);
}
private String doProcess(IntStuff i)
{
return String.format("%d", i.getValue());
}
private String doProcess(DoubleStuff d)
{
return String.format("%f", d.getValue());
}
}
public class Test {
public static void main(String[] args)
{
IntStuff iS = new IntStuff();
DoubleStuff dS = new DoubleStuff();
ProcessStuff pS = new ProcessStuff();
iS.setValue(5);
dS.setValue(23.2);
System.out.println(pS.process(iS));
System.out.println(pS.process(dS));
}
}
This, however, doesn't work, because calling doProcess(gS) expects a method with a signature doProcess(GeneralStuff gS).
I know I could just have two exposed polymorphic process methods in the ProcessStuff class, but the actual situation won't allow it because I'm working within the constraints of an existing library mechanism; this is just a contrived example for testing.
I could, of course, define process(GeneralStuff gS) as
public String process(GeneralStuff gS)
{
if (gS instanceof IntStuff)
{
return doProcess((IntStuff) gS);
}
else if (gS instanceof DoubleStuff)
{
return doProcess((DoubleStuff) gS);
}
return "";
}
which works, but it seems that I shouldn't have to do that (plus, the Programming Police would skewer me for using instanceof in this way).
Is there a way that I can enforce the polymorphic calls in a better way?
Thanks in advance for any help.
The type of dynamic dispatch you are looking for is not possible in Java without using reflection. Java does its linking at compile time based on the declared type (so even though a method is overloaded, the actual method invoked is based on the declared type of the variable not the runtime type).
So you are left with either using instanceof as you propose, using reflection, or putting the process methods in the objects themselves (which is the "oop" way to do it, but is often not suitable or advisable).
One potential alternative is to create a map of processing objects by class, eg:
Map<Class<? extends GeneralStuff>,Processor> processors;
public String process(GeneralStuff stuff)
{
Processor processor = processors.get(stuff.getClass());
if (processor != null)
{
return processor.process(stuff);
}
}
public interface Processor
{
public String process(GeneralStuff stuff);
}
public class IntegerProcessor implements Processor
{
public String process(GeneralStuff stuff)
{
return String.format("%i",((IntegerStuff) stuff).getValue());
}
}
However, for your specific example, String.format takes objects as the parameters, so you could avoid this whole issue by having getValue and getFormatString methods in GeneralStuff which are overriden in the specific subclasses.
You are actually on the right track, you indeed need to use reflection in this case. What you are looking for is sort of double dispatch, because you want the dispatch to be done on the dynamic type of the stuff parameter.
This type of switching-on-dynamic-type is not as rare as you think. See for example this javaworld tipe, which reflects on the visitor pattern
The compiler complains for good reason. There is no guarantee that your GeneralStuff object is an IntStuff or a DoubleStuff. It can be a plain GeneralStuff or any other extension of GeneralStuff, which is a case you also did not cover in your process method with the instanceof (unless returning the empty String was the desired behavior).
Is it not possible to move that process method into the GeneralStuff class and override it in the extensions ?
Another possible solution is to have a sort of composite ProcessStuff class in which you plug a IntStuffProcess, DoubleStuffProcess, ... instance . Each of those instances will still have the instanceof check to decide whether they can handle the GeneralStuff object passed to them, but this is at least more scalable/maintainable then one big instanceof construct
Perhaps, it's better to have overloaded process method in ProcessStuff:
public class ProcessStuff {
private String process(IntStuff i) {
return String.format("%d", i.getValue());
}
private String process(DoubleStuff d) {
return String.format("%f", d.getValue());
}
}
Define an GeneralStuff as an abstract class, with a doProcess method (abstract) which is filled in in the inheriting classes. This way you avoid all problems with instanceof values and such. Or you can do what is suggested by βнɛƨн Ǥʋяʋиɢ, but then you still would have to define an overload for each specific class, whereas in mine you just call it directly.
So my suggestion would be:
public abstract class GeneralStuff {
private int ID;
public abstract String process();
}
public class IntStuff extends GeneralStuff {
private int value;
public void setValue(int v)
{
value = v;
}
public int getValue()
{
return value;
}
#override
public String process(){
return String.format("%d", getValue());
}
}
public class DoubleStuff extends GeneralStuff {
private double value;
public void setValue(double v)
{
value = v;
}
public double getValue()
{
return value;
}
#override
public String process(){
return String.format("%f", getValue());
}
}
public class Test {
public static void main(String[] args)
{
IntStuff iS = new IntStuff();
DoubleStuff dS = new DoubleStuff();
ProcessStuff pS = new ProcessStuff();
iS.setValue(5);
dS.setValue(23.2);
System.out.println(iS.process());
System.out.println(dS.process());
}
}

Initializing private variables inside a constructor

I have been looking at this code for a comparator. My question is there a specific benefit of initializing the two private variables inside the constructor(Done here in the default constructor). I know the second constructor can be used to create an instance with supplied values. What difference would it make if I do
private String sortBy = COLUMN_LAST_NAME;
private boolean ascending = true;
I apologize if its a real simple and generic question.
public class CustomComparator implements Comparator<StudentList>
{ private String sortBy;
private boolean ascending;
public CustomComparator()
{
sortBy = COLUMN_LAST_NAME;
ascending = true;
}
public CustomComparator(String sortBy, boolean ascending)
{
this.sortBy = sortBy;
this.ascending = ascending;
}
The best practice i've seen preached everywhere is have one constructor that takes all parameters, even if it means it has to be private, and then just call it from other constructors using this(..,..,...) while supplying appropriate values.
This will make you reuse as much code as possible and future fixes go to one place and one place only - no need to make double maintenance of code.
Your example would look like this:
public class CustomComparator implements Comparator<StudentList> {
private String sortBy;
private boolean ascending;
public CustomComparator()
{
this(COLUMN_LAST_NAME, true);
}
public CustomComparator(String sortBy, boolean ascending)
{
this.sortBy = sortBy;
this.ascending = ascending;
}
}
Initialization is generally accepted to be in the constructor as to distinguish easier between static initialization of static members and per-instance init of instance variables. There is no performance difference.
Actually it matters if you care about object immutability (and you should :-)). If both of your fields are final, you must initialize them like this:
public class CustomComparator implements Comparator<StudentList> {
private final String sortBy;
private final boolean ascending;
public CustomComparator() {
sortBy = COLUMN_LAST_NAME;
ascending = true;
}
public CustomComparator(String sortBy, boolean ascending) {
this.sortBy = sortBy;
this.ascending = ascending;
}
}
Or even better:
public class CustomComparator implements Comparator<StudentList> {
private final String sortBy;
private final boolean ascending;
public CustomComparator() {
this(COLUMN_LAST_NAME, true);
}
public CustomComparator(String sortBy, boolean ascending) {
this.sortBy = sortBy;
this.ascending = ascending;
}
}
it's all about what you need, both constructor are good choices, obviuosly if you want to initialize the fields is the best choice but think if you use this class like an Entity on Hibernate or like a bean on Spring framework, if you dont write the empty constructor nothing will run fine...
if you think in DTO patterns, declaring inmutable fields like #Tomasz Nurkiewicz says then the parametrized constructor is the only choice....
but like i say before, it depends on requeriments...
I can't think of any difference and I prefer initializing in the variable declaration.

Categories