I had this listing and i can't see what is the porpouse:
DoubleProperty value = new DoublePropertyBase(0) {
#Override protected void invalidated() {
if (getValue() < get()) setValue(get());
}
#Override public String getName() { return "value"; }
};
Is like getValue() is the new Value and get() is the old, but the documentation does not say that.
If you look at the source code of the superclass of DoubleProperty you can see that both methods return the same value. get() returns the primitive type double and getValue() a Double object.
javafx.beans.binding.DoubleExpression
#Override
public Double getValue() {
return get();
}
javafx.beans.property.ReadOnlyDoubleProperty
#Override
public double get() {
valid = true;
final T value = property.getValue();
return value == null ? 0.0 : value.doubleValue();
}
Related
Given a very simple class:
class MyClass {
int id;
double value;
MyClass(int id) {
this.id = id;
}
void setValue(double v) {
value = v;
}
boolean isValueUnassigned() {
return value == 0;
}
}
To check if value has not been assigned yet, is it OK if I just do return value == 0; since a double is 0 by default?
You should go for wrapper class for double which is Double. For Double data type default value would be null. So that there would not be any ambiguity. If value is null, then it's not assigned any value.
Well, yes primitive double is set to 0.0 by default. But if you simply do return value == 0; you can't be sure if someone called setValue(0) before, but it is a valid assignment too. If you want to be 100% sure if someone called the setValue() I would suggest something like this:
class MyClass {
private int id;
private double value;
private boolean valueSet; // is false by default
public MyClass(int id) {
this.id = id;
}
public void setValue(double v) {
value = v;
valueSet = true;
}
public boolean isValueSet() {
return valueSet;
}
}
Adding to what #Harshal has already said. Code for something like that would look like:
class MyClass {
private int id;
private Double value;
public MyClass(int id) {
this.id = id;
}
public void setValue(double v) {
value = v;
}
public double getValue() {
//Check for null pointer and return
if(value == null)
return <whatever you want>;
return value.doubleValue();;
}
public boolean isValueSet() {
return (value == null ? false : true);
}
}
You can use Double to reinitialize the double using following
class MyClass {
int id;
Double value;
MyClass(int id) {
this.id = id;
}
void setValue(Double v) {
value = v;
}
boolean isValueUnassigned() {
return value == null ? false : true;
}
}
Explanation
The main issue here is that, whatever double value you choose, e.g. 0 or -1, it could actually be a valid value set by the user. In which case your application would falsely return that it was not set yet, while it was.
What you need is called a sentinel value, i.e. a special value that indicates this case. Typically there are 3 approaches:
Flag
Introduce a simple boolean flag boolean isSet which you initialize to false and set to true once it was set.
This approach is good and really fast. But does not scale well if you, for example, start to introduce hundreds of such values for which you need to represent "not set yet".
double value;
boolean isValueSet = false;
void setValue(double value) {
this.value = value;
isValueSet = true;
}
boolean isValueUnassigned() {
return !isValueSet;
}
Object wrapper
Object variables can, additionally to their actual values/instances also refer to null. This can be used as sentinel to indicate the special case.
So you could go for having the value internally represented as Double instead of double, starting with null.
The disadvantage is that an object introduces quite some memory and performance overhead compared to a simple primitive. In this case it does not really matter but if you scale this up to a couple of thousands of them, you would definitely start to feel the impact.
Double value = null;
void setValue(double value) {
this.value = value; // auto-boxing
}
boolean isValueUnassigned() {
return value == null;
}
Sentinel value
If you application naturally allows that some values can never be used, you can use them as sentinel to indicate the case. A common example would be an age field for which you would not allow the user to set it to negative values. Then you can use, for example -1 to indicate it.
This approach is quite common and efficient. But it obviously is not always applicable and it is also not necessarily the most readable/maintainable approach.
double value = -1;
void setValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Negative values are not allowed");
}
this.value = value;
}
boolean isValueUnassigned() {
return value == -1;
}
The value is assigned when the object is created. You don't need a method to check if the value has been assigned because the answer is always yes.
Found the cleanest and clearest way to express it:
class MyClass {
int id;
Optional<Double> value;
MyClass(int id) {
this.id = id;
this.value = Optional.empty();
}
void setValue(double v) {
value = Optional.of(v);
}
double getValue() {
if (isValueUnassigned) {
throw new RuntimeException("Value has not been assigned");
}
return value.get();
}
boolean isValueUnassigned() {
return value.isEmpty();
}
}
a double value is 0 by default , but you can pass -1 to it .
double value = -1;
for check :
if (value!= -1) {
// To Do
}
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()
My program loads information from a text file and creates an array of an object with the information whether it is a integer or a string.
I then want the object to return either a String or an Integer depending on whether the object is holding a integer value or a string value.
edit...
So here is my type class that holds either a int if the field in the text file is a number, or a string if the field is a word, and this is held in a Type array.
public class Type {
private String name;
private int value;
public Type(String name) {
this.name = name;
}
public Type(int value) {
this.value = value;
}
public String getName() {
return this.name;
}
public int getValue() {
return this.value;
}
public boolean isInt() {
boolean isInt = false;
if (this.value != 0) {
isInt = true;
return isInt;
}
return isInt;
}
}
So in my array could be either a Int or a String, i want to return the datatype without any long statements in my main class.
If you strictly want only to get the specific values, you could add a method to your Type class and get the values from this method, ugly but does what you want:
public <T> T getDynamicValue(Type t) {
if (isInt()) {
return (T) ((Integer) t.getValue());
} else {
return (T) t.getName();
}
}
use of it:
List<Type> dynamicList = Arrays.asList(new Type[]{new Type(1), new Type(2), new Type("dog")});
for (Type t : dynamicList) {
System.out.println("T -> " + t.getDynamicValue(t));
}
If you want to perform some manipulation with this data, you have to make an instanceof check and Cast it, for instance some splitting (or String methods) with the name value...
You can't choose the type of object to return at runtime. Your only option is to return an Object. You can check if it's a String or an int using this code, for example:
if(object instanceof String) {
//... it's a string
}
else {
//...otherwise it's an int
}
If you are reading all inputs into String instances, you will need to test the values against Integer.parseString(value) to find out if it is actually an Integer.
You could try to cast the object into an Integer and catch the ClassCastException:
try {
int i = (Integer) object;
}
catch (ClassCastException e){
String s = (String) object;
}
When I have this type of problem, I sometimes solve it by turning the problem around and using a callback-style solution.
For example:
for ( Type t : array ) {
t.process( callback );
}
Where the callback looks like this:
interface Callback {
public void processInt(....);
public void processString(....);
}
You can then either implement the process method either with an if (isInt()) callback.processInt() else callback.processString(), or if you change the definition of Type you can use the inheritance tree to do it for you.
For example:
interface Type {
public void process( Callback cb );
}
class IntType implements Type {
public void process( Callback cb ) {
cb.processInt(...);
}
}
class StringType implements Type {
public void process( Callback cb ) {
cb.processString(...);
}
}
I have a class called monetary
public class Monetary
{
double value;
String type;
public Monetary()
{
value = 0;
type = "";
}
public double getValue()
{
return value;
}
public void setValue(double x)
{
x = this.value;
}
and i was testing get and set methods so i made a testing class as the following
public class test
{
public static void main(String [] args)
{
double test = 5000;
Monetary testM = new Monetary();
testM.setValue(5000);
System.out.println(testM.getValue());
}
}
The problem is that the result java prints is not 5000.0, but 0. I don't get why this is happening. Aren't these methods correct?
The problem is in the setValue method:
public void setValue(double x) {
x = this.value;
}
You're assigning the parameter the current value of the attribute, it should be backwards:
public void setValue(double x) {
this.value = x;
}
Note that even doing this, you will get an output like 5000.0000000.... In order to fix the result you can use String#format or System.out.printf:
System.out.println(String.format("%.2f", testM.getValue()));
or
System.out.printf("%.2f\n", testM.getValue());
In your code you are assigning the value to parameter x, it should be opposite.
public void setValue(double x){
this.value = x;
}
try this:
public void setValue(double x)
{
this.value = x;
}
public void setValue(double x){
this.value = x;
}
You are assigning the parameter you've passed x with the default value of the value. You must be doing the exact opposite of that. Assign the value with the value passed x.
Hence, instead of this this.value = 5000, this is happening x = 0.
You are assigning the parameter (double x) the value of int value which does nothing because you are return value, so what you want to do is
public class Monetary
{
double value;
String type;
public Monetary()
{
value = 0;
type = "";
}
public double getValue()
{
return value;
}
public void setValue(double x)
{
value = x;//change this
}
i am trying to use the following code...
The Enum class i am using is
public enum AccountType {
kAccountTypeAsset(0x1000),
kAccountTypeAssetFixed(0x1010),
private int value;
private AccountType(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
}
public AccountType accountType = kAccountTypeAsset;
integerToDB(accountType);
...
/*************************/
public Object integerToDB (Integer i )
{
if(i == -1)
{
return null;
}
return i;
}
How can i use
accountType
as integer.
integerToDB(accountType.getValue()); ?
Since your enum has implemented a getValue method, you can use accountType.getValue() to get the integer value stored in accountType.