Charles Bryant Charles Bryant - 2 months ago 6
Java Question

Java class property that can support different types

I am building a content management system with Java, I have a class to express an Entity, and a class to express a Field within the Entity.

Currently my Field class as an array list of String to store all of the values.

My class looks like this:

public class Field implements Serializable {
private UUID key;
private String name;
private ArrayList<String> values;
private Integer maxValues;
private ValueType type;
private String code;

public enum ValueType {
INT,
VARCHAR,
DATE,
BOOLEAN
}

public void addValue(String value){
if (this.values.size() < this.maxValues){
this.values.add(value);
}
}

public ArrayList<String> getValues(){
return this.values;
}
}


I would like to store String, Integer, Floats and Dates, I am thinking I could type check the values when they are entered and have separate methods for getting the values as the correct types.

public ArrayList<Integer> getIntegerValues(){

ArrayList<Integer> integerValues = new ArrayList<Integer>();


values.forEach(
(v) -> {

Integer intValue = Integer.parseInt(v);

integerValues.add(intValue);

}
);

return integerValues;
}


I figure this would work but it does not feel like a great solution, as when using this class you would have to select the correct function to get the types. It would be good if there was just a single function to return the correct version.

Does anyone have any ideas how I can write this better.

Answer

I was not 100% happy with either answer, neither felt like the right way to solve this issue, both ways had issues to deal with. However I realised that both answers together will give a nice solution, so thanks to both.

Your concrete class will define the values for the generic value. This will satisfy the open closed principal.

public interface FieldType<T> {
    void addValue(T value);
    ArrayList<T> getValues();
}

public abstract class Field<T> implements FieldType<T>, Serializable {
    private UUID key;
    private String name;
    protected ArrayList<T> values;
    private Integer maxValues;
    private String code;

    public abstract void addValues();

    public ArrayList<T> getValues(){
        return this.values;
    }
}

public class FloatField extends Field<Float> {

    @Override
    public void addValue(Float value) {
        this.values.add(value);
    }

    @Override
    public ArrayList<Float> getValues() {
        return this.values;
    }
}