public Object getValue()
{
ValueItem valueItem = null;
Object returnValue = null;
if(this.value instanceof StringValueImpl)
{
valueItem = (StringValueImpl) this.value;
}
else if(this.value instanceof ListValueImpl)
{
valueItem = (ListValueImpl) this.value;
}
else if(this.value instanceof MapValueImpl)
{
valueItem = (MapValueImpl) this.value;
}
if(valueItem!=null)
returnValue = valueItem.getValue();
return returnValue;
}
ValueItem is an interface which is implemented by ListValueImpl, MapValueImpl etc .. I want return value which is an object. The code works fine but i was wondering if this can be improved in any way ?
What is the type of this.value? If it is ValueItem then you don't need to do any of this and can replace the method with this:
public Object getValue()
{
Object returnValue = null;
if(this.value!=null)
returnValue = this.value.getValue();
return returnValue;
}
Or even shorter:
public Object getValue()
{
return this.value!=null ? this.value.getValue() : null;
}
If this.value is not of type ValueItem but it has to contain a ValueItem, then you have a design problem at your hand.
My inclination is that your getValue() isn't doing anything for you at all. You're detecting what class it is, casting it to that class, then shoving it into an Object again. ...so you'll have to do the same kind of detection on the caller's side of getValue() anyways!
Personally, I'd do it like this:
public boolean isaStringValueImpl() {
return (this.value instanceof StringValueImpl);
}
public boolean isaListValueImpl() {
return (this.value instanceof ListValueImpl);
}
public boolean isaMapValueImpl() {
return (this.value instanceof MapValueImpl);
}
public StringValueImpl getAsaStringValueImpl() {
return (StringValueImpl)this.value;
}
public ListValueImpl getAsaListValueImpl() {
return (ListValueImpl)this.value;
}
public MapValueImpl getAsaMapValueImpl() {
return (MapValueImpl)this.value;
}
In addition to the regular getter:
public ValueItem getValueItem() {
return this.value;
}
But even with all this, I'd say that you might have a larger design issue that could be cleaned up.
How about a generics based type safe version.
public abstract class ValueItem<T> {
public abstract T getValue();
public class StringValueImpl extends ValueItem<String> {
private String value;
public String getValue() {
return value;
}
}
public class ListValueImpl extends ValueItem<List<?>> {
private List<?> value;
public List<?> getValue() {
return value;
}
}
public class MapValueImpl extends ValueItem<Map<?, ?>> {
private Map<?, ?> value;
public Map<?, ?> getValue() {
return value;
}
}
}
Related
I've got a class that looks something like.
public class ParseValue {
public String value;
public final Class classType;
}
And I'd like to make a function that does a conversion and returns a casted value.
public T parseValue(ParseValue parseInfo) {
if(parseInfo.classType == String.class) {
return parseInfo.value;
} else if (parseInfo.classType == Double.class) {
return Double.valueOf(parseInfo.value);
}
}
Right now I can have this function return an Object and then cast it upon getting the result, but is there a way to make the function do the cast based on the input ParseValue's classType field?
The safest way to do it is to make ParseValue generic:
public class ParseValue<T> {
public String value;
public final Class<T> classType;
public T parseValue() {
Object result;
if (classType == String.class) {
result = value;
} else if (classType == Double.class) {
result = Double.valueOf(value);
} else {
throw new RuntimeException("unknown value type");
}
return classType.cast(result);
}
}
I have two classes which pretty much implement the same operations for two different numeric types (except for the getHexadecimalValue() method):
public class IntegerType
{
private int value;
public IntegerType()
{
value = 0;
}
public void setValue(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
public String getHexadecimalValue()
{
int integerValue = (int) getValue();
String hexadecimal = ValueConversions.toHexadecimal(integerValue);
return hexadecimal;
}
}
and
public class FloatingPointType
{
private float value;
public FloatingPointType()
{
value = 0;
}
public void setValue(float value)
{
this.value = value;
}
public float getValue()
{
return value;
}
public String getHexadecimalValue()
{
float floatingValue = (float) getValue();
int intBits = Float.floatToRawIntBits(floatingValue);
return ValueConversions.toHexadecimal(intBits);
}
}
I'm wondering what the best way would be to reduce this redundancy by e.g. defining a superclass called NumberType like this:
public abstract class NumberType
{
protected Number value;
public NumberType()
{
setValue(0);
}
public void setValue(Number value)
{
this.value = value;
}
public Number getValue()
{
return value;
}
public abstract String getHexadecimalValue();
}
Now the problem is that any number can be passed to my inheriting classes but I only want to accept ints and floats respectively while still keeping redundancy to a minimum:
public class IntegerType extends NumberType
{
#Override
public String getHexadecimalValue()
{
// Crashes on runtime if the value doesn't happen to be of the expected type
int integerValue = (int) getValue();
String hexadecimal = ValueConversions.toHexadecimal(integerValue);
return hexadecimal;
}
}
Can this be done by still keeping proper type checking?
You can try this way.
public abstract class NumberType<T extends Number> {
protected T value;
public NumberType(T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public abstract String getHexadecimalValue();
}
public class FloatingPointType extends NumberType<Float> {
public FloatingPointType() {
super(0f);
}
public String getHexadecimalValue() {
return ValueConversions.toHexadecimal(Float.floatToRawIntBits(value));
}
}
Note: Float and Integer, both class has static toHexString methods which you can directly use if you are comfortable to use them.
public static String toHexString(float f)
public static String toHexString(int i)
This can be done with overloading
for example:
public abstract class NumberType
{
private Number value;
public NumberType()
{
setValue(0);
}
public void setValue(float value)
{
this.value = value;
}
public void setValue(int value)
{
this.value = value;
}
public Number getValue()
{
return value;
}
public abstract String getHexadecimalValue();
}
You can also add then:
public int getIntValue()
{
return value.intValue();
}
public float getFloatValue()
{
return value.floatValue();
}
Ideally, setValue(Number value) must not allow entering any value but float in FloatingPointType and setValue(Number value) must not allow entering any value but int in IntegerType. You can check by using intValue() and floatValue() methods in class Number and throw exception if inappropriate value entered. Number class methods
It would be something like this in setValue(Number value) of IntegerType
if(value.intValue()!= value)
throw new IllegalArgumentException()
I am overriding equals method of a class to compare two objects since I want to compare all the fields of it. If two objects are unequal, is there a way to find out which of the fields were unequal due to which the objects are unequal?
You could write a method in the class that returns an object of the same type with either the difference or null for each data member. Or you can find a library that does it for you. Try http://javers.org
Create class to strore fields information like this (or use Map):
class FieldsContainer<F,V>{
private F field;
private V value;
public FieldsContainer(F field, V value) {
this.field = field;
this.value = value;
}
public FieldsContainer(){}
public F getField() {
return field;
}
public void setField(F field) {
this.field = field;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
and then in equals():
public boolean equals(Object obj) {
...
} else if (!field1.equals(other.field1)){
fieldsContainer=new FieldsContainer("fieldName1", field1);
return false;
}
if (field2 != other.field2){
fieldsContainer=new FieldsContainer("fieldName2", field2);
return false;
}
fieldsContainer=null;
return true;
}
and in main:
if(!obj1.equals(obj2)){
fieldsContainer.getField();
fieldsContainer.getValue();
//Your stuff
}
I'm totally confused with java generics now trying to resolve the following thing.
I have the function:
private static Enum<?> findEnumValue(final Class<Enum<?>> cls, final Object value)
{
if (value == null) {
return null;
}
if (value instanceof Enum<?>) {
return (Enum<?>) value;
}
if (value instanceof String) {
for (Enum<?> item : cls.getEnumConstants()) {
if (item.name().equals(value)) {
return item;
}
}
}
return null;
}
And I'm trying to pass to this function an ordinary enum, say, Name and it's value JOHN like this:
findEnumValue(Name.class, Name.JOHN.name())
but this doesn't work. Could somebody, please, point me to my mistakes and explain what i'm doing wrong.
Here is the Name enum:
public enum Name {
JOHN,
MARK;
}
Thanks you all for help!
You could use Class<? extends Enum<?>> instead of Class<Enum<?>>. Name.class is not a Class<Enum<?>>.
private static <T extends Enum<T>> T findEnumValue(final Class<T> cls,
final Object value) {
if (value == null) {
return null;
}
if (value.getClass() == cls) {
return cls.cast(value);
}
if (value instanceof String) {
return Enum.valueOf(cls, (String)value);
}
return null;
}
private static <T extends Enum<T>> T findEnumValue(final Class<T> cls, final Object value)
{
if (value == null) {
return null;
}
if (value instanceof Enum<?>) {
return (T) value;
}
if (value instanceof String) {
for (T item : cls.getEnumConstants()) {
if (item.name().equals(value)) {
return item;
}
}
}
return null;
}
I want to make the class below immutable. Can anyone provide a simple example of creating an immutable class in java?
class Emp implements Comparable
{
String name,job;
int salary;
public Emp(String n,String j,int sal)
{
name=n;
job=j;
salary=sal;
}
public void display()
{
System.out.println(name+"\t"+job+"\t"+salary);
}
public boolean equals(Object o)
{
// use a shortcut comparison for slightly better performance; not really required
if (this == o)
{
return true;
}
// make sure o can be cast to this class
if (o == null || o.getClass() != getClass())
{
// cannot cast
return false;
}
// can now safely cast
Emp p=(Emp)o;
return this.name.equals(p.name)&&this.job.equals(p.job) &&this.salary==p.salary;
}
public int hashCode()
{
return name.hashCode()+job.hashCode()+salary;
}
public int compareTo(Object o)
{
Emp e=(Emp)o;
return this.name.compareTo(e.name);
//return this.job.compareTo(e.job);
// return this.salary-e.salary;
}
}
Just label all fields of your class as final, and don't assign to them anywhere but the constructor for your class.
Also, it's good to make the class final, or to only provide private constructors, and static factory methods. This means people cannot subclass your class and override you methods.
for example:
public class Immutable {
private final String value;
private Immutable(String value) {
this.value = value;
}
public static Immutable create(String value) { return new Immutable(value); }
public String getValue() { return value; }
}