How to validate a double value which accepts either integers or values with .5 (Java)

Viewed 102

I'm defining attributes for a house class and need to validate them inside the constructor method, below is the attribute and the explanation of the validation I have to do.

numberBathrooms – a double value that identifies the number of bathrooms in this house. This value must a number greater than zero with an optional fraction value of 0.5. For example, 1.5 and 0.5 are valid values while 2.7 and 0.4 are not valid.

Below is my code for my class which is inheriting from my other building class.

public class house extends building {

double numberBathrooms;
int numberBedrooms;

public void house(String name, String number, int buildYear, double bathrooms, int bedrooms){
    if (name == null || number == null) {
        System.out.println("Street values cannot be empty");
    } 
    else if (buildYear < 1975 || buildYear > 2019) {
        System.out.println("Year is not in a valid range");
    }
    else if(bathrooms <= 0 || bathrooms //Something here?){

    }
    else {
        streetName = name;
        streetNumber = number;
        yearBuilt = buildYear;
        bathrooms = numberBathrooms;
        bedrooms = numberBedrooms;
    }
}

Is there any logic I can use (as used in my other parameters)? or is there a more effective way maybe.

4 Answers
public class House extends Building {

private double numberBathrooms;
private int numberBedrooms;

public void House(String name, String number, int buildYear, double bathrooms, int bedrooms){
    super(name, number, buildYear);
    if (name == null || number == null) {
        System.out.println("Street values cannot be empty");
    } 
    else if (buildYear < 1975 || buildYear > 2019) {
        System.out.println("Year is not in a valid range");
    }
    else if(bathrooms <= 0 || bathrooms % 0.5 != 0){
        System.out.println("Bathrooms is not in a valid range");
    }
    else {
        this.numberBathrooms = bathrooms;
        this.numberBedrooms = bedrooms;
    }
}

Some suggestions:

  • Use capital letters as the first letter for Class names, no error will be thrown but still, it is the convention.

  • Use super() to instantiate the members of parent class.

  • Make data members private and write getters and setters for them.

You could use:

    ...
    else if(bathrooms <= 0 || bathrooms % 0.5 != 0){

    }
    ...

This will take your number modulo a half to see if there is any remainder.

You can check my work here and rapidly prototype using jshell. For example:

my prompt>  jshell 
|  Welcome to JShell -- Version 11
|  For an introduction type: /help intro

jshell> 1.7 % .5
$1 ==> 0.19999999999999996

jshell> 1.5%0.5
$2 ==> 0.0

jshell> 1%0.5
$3 ==> 0.0

Note: this only works because floating point numbers will faithfully represent small numbers where x = m/(2^n)

Using % will work in this case, it doesn't work for a more general case e.g. 1 % 0.1 = 0.09999999999999995 It happens to work here as 0.5 can be represented precisely.

A better pattern is to represent it as a long.

if ((long) (bathroom * 2) / 2 != bathroom)

or if you prefer for clarity

if (Math.round(bathroom * 2) / 2 != bathroom)

You could use pattern-matching

Pattern numpat = Pattern.compile( "\\d\\.((?<!0\\.)0|5)" );
Matcher m = numpat.matcher( "" + numberBathrooms );
if( ! m.matches() )
  System.err.println( "invalid" );

valid:    0.5, 1, 1.5
invalid: 0, 0.4, 2.7

Related