So i am trying to generate a house(at this point a very simple house) and I have this Class:
public class Probability {
public final int MinWindows = 0;
public final int MaxWindows = 0;
//double values represend the percent chance for a specific attribute to
//generate
public final double hasBackDoor = 0;
public final double hasSecondFloor = 0;
public final double hasChimny = 0;
public final double hasGarage = 0;
public final double hasPorch = 0;
}
This class is then inherited by subclasses for different types of houses:
public class LowClassHouseProbability extends Probability{
public final int MinWindows = 5;
public final int MaxWindows = 10;
public final double hasBackDoor = 55.0;
public final double hasSecondFloor = 10.0;
public final double hasChimny = 5.5;
public final double hasGarage = 30.0;
public final double hasPorch = 60.0;
}
public class MiddleClassHouseProbability extends Probability{
public final int MinWindows = 20;
public final int MaxWindows = 50;
public final double hasBackDoor = 80.0;
public final double hasSecondFloor = 70.0;
public final double hasChimny = 10.0;
public final double hasGarage = 90.0;
public final double hasPorch = 85.0;
}
public class UpperClassHouseProbability extends Probability{
public final int MinWindows = 50;
public final int MaxWindows = 100;
public final double hasBackDoor = 100.0;
public final double hasSecondFloor = 100.0;
public final double hasChimny = 80.0;
public final double hasGarage = 99.0;
public final double hasPorch = 100.0;
}
So all of the subclasses of Probability shadow all of its fields which in my opinioin looks sloppy and is kind of annoying to read, however i need them to extend Probability because it would make it easyer when i actually have to use the object, because it looks nicer doing this:
public class House {
public House(Probability prob){
}
}
Than if i did not have a Probability class and did this:
public class House {
public House(LowClassHouseProbability prob){
}
public House(MiddleClassHouseProbability prob){
}
public House(UpperClassHouseProbability prob){
}
}
And this would only get worse with the more sub-classes that I create.
So my question is is there a better way of doing this that I'm not thinking of, or do i just have to do it one way or the other of the two solutions that I thought of.
Since you can not override fields from the super class in java those classes dont need at all to define the field..
public class LowClassHouseProbability extends Probability{
//public final int MinWindows = 50;
//public final int MaxWindows = 100;
those all are final declared so you need to set those in the constructor...
LowClassHouseProbability(int minW, int maxW,...){
super(minW, maxW, ....);
MiddleClassHouseProbability(int minW, int maxW,...){
super(minW, maxW, ....);
UpperClassHouseProbability(int minW, int maxW,...){
super(minW, maxW, ....);
and in the superclass Probability define the constructor:
Probability(int minW, int maxW,...){
MinWindows = minW;
MaxWindows = maxW;
// .... etc etc
It's probably best to remove the child classes altogether and define instances of the Probability class pertinent to your house types, and build a multi-argument constructor to facilitate instance construction.
Alternatively, you could refactor this into an interface:
public interface Probability {
int getMinWindwsMinWindows();
/*and so on*/
}
Then,
public class LowClassHouseProbability implements Probability{
{
#Override
int getMinWindwsMinWindows()
{
return 5;
}
/*and so on*/
}
The problem of managing constructors with too many fields can be solved by using a step builder. A step builder works by creating an interface for each step, then having the builder implement all of them. This way after completing each build step, only the next step is available to complete.
Here's an example:
package mcve;
public class Probability {
public final int minWindows;
public final int maxWindows;
public final double hasBackDoor;
public final double hasSecondFloor;
public final double hasChimny;
public final double hasGarage;
public final double hasPorch;
private Probability(final int minWindows,
final int maxWindows,
final double hasBackDoor,
final double hasSecondFloor,
final double hasChimny,
final double hasGarage,
final double hasPorch) {
this.minWindows = minWindows;
this.maxWindows = maxWindows;
this.hasBackDoor = hasBackDoor;
this.hasSecondFloor = hasSecondFloor;
this.hasChimny = hasChimny;
this.hasGarage = hasGarage;
this.hasPorch = hasPorch;
}
public static final Probability LOW_CLASS =
builder().setMinWindows(5)
.setMaxWindows(10)
.setHasBackDoor(55.0)
.setHasSecondFloor(10.0)
.setHasChimny(5.5)
.setHasGarage(30.0)
.setHasPorch(60.0)
.build();
// public static final Probability MIDDLE_CLASS = ...;
// public static final Probability UPPER_CLASS = ...;
public static MinWindowsStep builder() {
return new Builder();
}
public interface MinWindowsStep { MaxWindowsStep setMinWindows(int n); }
public interface MaxWindowsStep { HasBackDoorStep setMaxWindows(int n); }
public interface HasBackDoorStep { HasSecondFloorStep setHasBackDoor(double n); }
public interface HasSecondFloorStep { HasChimnyStep setHasSecondFloor(double n); }
public interface HasChimnyStep { HasGarageStep setHasChimny(double n); }
public interface HasGarageStep { HasPorchStep setHasGarage(double n); }
public interface HasPorchStep { BuildStep setHasPorch(double n); }
public interface BuildStep { Probability build(); }
private static final class Builder
implements MinWindowsStep,
MaxWindowsStep,
HasBackDoorStep,
HasSecondFloorStep,
HasChimnyStep,
HasGarageStep,
HasPorchStep,
BuildStep {
private int minWindows;
private int maxWindows;
private double hasBackDoor;
private double hasSecondFloor;
private double hasChimny;
private double hasGarage;
private double hasPorch;
#Override
public MaxWindowsStep setMinWindows(int minWindows) {
this.minWindows = minWindows;
return this;
}
#Override
public HasBackDoorStep setMaxWindows(int maxWindows) {
this.maxWindows = maxWindows;
return this;
}
#Override
public HasSecondFloorStep setHasBackDoor(double hasBackDoor) {
this.hasBackDoor = hasBackDoor;
return this;
}
#Override
public HasChimnyStep setHasSecondFloor(double hasSecondFloor) {
this.hasSecondFloor = hasSecondFloor;
return this;
}
#Override
public HasGarageStep setHasChimny(double hasChimny) {
this.hasChimny = hasChimny;
return this;
}
#Override
public HasPorchStep setHasGarage(double hasGarage) {
this.hasGarage = hasGarage;
return this;
}
#Override
public BuildStep setHasPorch(double hasPorch) {
this.hasPorch = hasPorch;
return this;
}
#Override
public Probability build() {
return new Probability(minWindows,
maxWindows,
hasBackDoor,
hasSecondFloor,
hasChimny,
hasGarage,
hasPorch);
}
}
}
Fields have to be assigned by name, and if you forget which step you are on, the compiler error will tell you:
// This will cause an error with a message something like
// "Cannot find symbol method build() in interface MinWindowsStep".
Probability p = Probability.builder()
.build();
If it turns out that it really is the case that you need to use inheritance, the builder pattern can be adapted to that by having e.g. an abstract build step with multiple implementations.
Related
I try to code a builder pattern for my better understanding. Mostly I relied on GOF and wikipedia.
So my Object is a house with required attribute area and some optional attributes (like windows, doors, rooms etc.)
I will show you the code. Now, I'm not really sure if its correct and I think I don't have a director? I don't get in which cases you need one and how it works.
This is my class house and the innerclass HouseBuilder
public class House {
//required
private final String area;
//optional
private int windows;
private int doors;
private int rooms;
//constructor with HouseBuilder
private House(HouseBuilder builder) {
this.windows = builder.windows;
this.doors = builder.doors;
this.rooms = builder.rooms;
}
public static class HouseBuilder {
//required
private String area;
//optional
private int windows;
private int doors;
private int rooms;
//constructor with required attributes
HouseBuilder(String area) {
this.area = area;
}
//optional attributes
public HouseBuilder windows(int windows) {
this.windows = windows;
return this;
}
public HouseBuilder doors (int doors) {
this.doors = doors;
return this;
}
//function for building
public Housebuild() {
return new House(this);
}
}
Now, I just got a class demo where I can build a house like that:
House house = new House.HouseBuilder("Downtown")
.doors(3).windows(2).build();
But this is not a director like in the books. Is my idea even correct? And why is that better than just using setters?
Thanks!
Your example illustrates classic builder. Director is something like an abstract builder, and in practise it is rarely used because the client class can handle that perfectly well. Example of a director in your case would be:
public class House
{
public final String area;
public windows;
public int doors;
public int rooms;
}
interface HouseBuilder
{
public HouseBuilder area();
public HouseBuilder windows();
public HouseBuilder doorsors();
public HouseBuilder rooms();
public House build();
}
public static class DowntownHouseBuilder implements HouseBuilder
{
House downtownHouse = new House();
public HouseBuilder area()
{
downtownHouse.area = "Downtown";
}
public HouseBuilder windows()
{
downtownHouse.windows = 3;
return this;
}
public HouseBuilder doors()
{
downtownHouse.doors = 2;
return this;
}
public HouseBuilder rooms()
{
downtownHouse.rooms = 2;
return this;
}
public House build()
{
return downtownHouse;
}
}
public static class VilaBuilder implements HouseBuilder
{
House vila new House();
public HouseBuilder area()
{
vila.area = "Downtown";
}
public HouseBuilder windows()
{
vila.windows = 24;
return this;
}
public HouseBuilder doors()
{
vila.doors = 5;
return this;
}
public HouseBuilder rooms()
{
downtownHouse.rooms = 10;
return this;
}
public House build()
{
return vila;
}
}
class Driector
{
private HouseBuilder houseBuilder;
public Driector(HouseBuilder houseBuilder)
{
this.houseBuilder = houseBuilder;
}
public House buildHouse()
{
return this.houseBuilder.area()
.windows()
.doors()
.rooms()
.buid();
}
}
class HouseConstruction
{
public static void main(String[] args)
{
Director director = new Director(new VilaBuilder());
House house = director.buildHouse();
System.out.println("Builder constructed: "+ house);
}
}
Hope this helps clarify what is a Director in Builder pattern.
I want to use some object of one class and use in other class,but i can not
for example :
class 1:
public class Value {
private double radious;
private double lenght;
public void setRadious(double radious) {
this.radious = radious;
}
public void setLenght(double lenght) {
this.lenght = lenght;
}
}
question : how can I use just radious of class 1 in class 2???
class 2:
public class calculateArea
{
private Value value;
public double area()
{
return 3.14*radious*radious;
}
}
Create getters for both the values and access them in your second class.
Something like
public double getRadious() {
return this.radious;
}
public double getLenght() {
return this.lenght;
}
When working on OOP, ask yourself what code goes where and how many classes you have to make?
For your scenario, you can use aggregation or composition which is to declare the object of one class in another and then you can call the methods of the declared object using dot notation with getter setter methods. So it will go like this.
public class Value
{
private double radious;
private double lenght;
public void setRadious(double radious)
{
this.radious = radious;
}
public double getRadious() {
return this.radious;
}
public double getLenght() {
return this.lenght;
}
public void setLenght(double lenght)
{
this.lenght = lenght;
}
}
Class # 2
public class calculateArea
{
private Value value = new Value();
public calculateArea(double rad) {
value.setRadius(rad);
}
public double area()
{
return 3.14*value.getRadious()*value.getRadious();
}
}
Also, you need to set the value of radius before using it.
Make a getter Method for radious:
public double getRadious(){
return radious;
}
In the "Main Class":
Value v = new Value();
v.setRadious(2.5);/*Set the Radious value*/
public double area()
{
return 3.14*v.getRadious()*v.getRadious();
}
Add getters to class Value.
public class Value {
public double radious;
public double lenght;
public void setRadious(double radious) {
this.radious = radious;
}
public void setLenght(double lenght) {
this.lenght = lenght;
}
public double getLenght() {
return this.lenght;
}
public double getRadious() {
return this.radious;
}
}
Make an instance of class 1
public class calculateArea{
public Value;
calculateArea(){
value = new Value();
}
public double area(){
value.setRadious(2.34);//or set ACCORDINGLY
return 3.14 * value.radious * value.radious;
}
}
Declare getters and setters for Value-class:
public class Value {
private double radious;
private double lenght;
public Value(double radious, double length) {
this.radious = radious;
this.length = length;
}
public void setRadious(double radious) {
this.radious = radious;
}
public void setLenght(double lenght) {
this.lenght = lenght;
}
public double getRadious() {
return this.radious;
}
public double getLength() {
return this.length;
}
}
Instantiate the object with some variables:
Value value = new Value(2.0,3.0);
Add Constructor to CalculateArea class:
public class calculateArea {
private Value value;
public calculateArea(Value value) {
this.value = value;
}
public double area()
{
return 3.14*value.getRadious()*value.getRadious();
}
}
Instantiate:
calculateArea cArea= new calculateArea(value);
And print result to console in main() method:
System.out.println(cArea.area());
I implemented pattern based on this answer
I have the following asbtract config:
public abstract class AbstractConfig {
public static abstract class Builder<B extends Builder<B>> {
private int calories = 0;
public Builder() {
}
public B setCalories(int calories) {
this.calories = calories;
return (B) this;
}
public abstract AbstractConfig build();
}
private int calories = 0;
protected AbstractConfig(final Builder builder) {
calories = builder.calories;
}
}
And I have the following concrete config:
public class DialogConfig extends AbstractConfig {
public static class DialogConfigBuilder<B extends DialogConfigBuilder<B>> extends Builder<B> {
private double width;
private double height;
public DialogConfigBuilder() {
//does nothing.
}
public B setWidth(final double value) {
width = value;
return (B) this;
}
public B setHeight(final double value) {
height = value;
return (B) this;
}
public DialogConfig build() {
return new DialogConfig(this);
}
}
private final double width;
private final double height;
protected DialogConfig(final DialogConfigBuilder builder) {
super(builder);
width = builder.width;
height = builder.height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
And this is how I use it
DialogConfig config = new DialogConfig.DialogConfigBuilder()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
At X line I get - Can't find symbol method setHeight. What is my mistake?
EDIT - I will have and a ExtendedDialogConfig that must extend DialogConfig and etc. I mean there will be other subclasses.
You would first change setCalories() to:
public Builder<B> setCalories(int calories) {
this.calories = calories;
return this;
}
to get rid of that cast and the warning. And now look at this closely. You return a Builder. This code doesn't know about future subclasses. It only returns an instance of that base builder.
As a consequence, when you have that chained call:
.setHeight(0) .build();
that would return that base builder. To then call build() - which would build an abstract configuration. But you want to assign that to a more specific DialogConfig. Thus the error.
A (ugly) workaround:
DialogConfig.DialogConfigBuilder<?> builder = new DialogConfig.DialogConfigBuilder<>().setHeight(0);
builder.setCalories(0);
...config = builder.build();
And a solution - by again reworking setCalories():
#SuppressWarnings("unchecked")
public <T extends B> T setCalories(int calories) {
this.calories = calories;
return (T) this;
}
Fixes the compile error; and allows chaining the setCalories() call as well. Final exercise of getting rid of the cast/suppress is left as exercise to the reader.
And for the record - the "complete" solution, including all adaptions to get rid of raw types and other warnings:
abstract class AbstractConfig {
public static abstract class Builder<B extends Builder<B>> {
private int calories = 0;
#SuppressWarnings("unchecked")
public <T extends B> T setCalories(int calories) {
this.calories = calories;
return (T) this;
}
public abstract AbstractConfig build();
}
private int calories = 0;
public int getCalories() { return calories; }
protected <B extends Builder<B>> AbstractConfig(final Builder<B> builder) {
calories = builder.calories;
}
}
final class DialogConfig extends AbstractConfig {
public static class DialogConfigBuilder<B extends DialogConfigBuilder<B>> extends Builder<B> {
private double width;
private double height;
public DialogConfigBuilder<B> setWidth(final double value) {
width = value;
return this;
}
public DialogConfigBuilder<B> setHeight(final double value) {
height = value;
return this;
}
public DialogConfig build() {
return new DialogConfig(this);
}
}
private final double width;
private final double height;
protected <B extends DialogConfigBuilder<B>> DialogConfig(final DialogConfigBuilder<B> builder) {
super(builder);
width = builder.width;
height = builder.height;
}
public double getWidth() { return width; }
public double getHeight() { return height; }
}
public class Builders {
public static void main(String[] args) {
DialogConfig config = new DialogConfig.DialogConfigBuilder<>().setHeight(0).setCalories(0).build();
System.out.println(config);
}
}
I found my mistake. This is how I used DialogConfigBuilder
DialogConfig config = new DialogConfig.DialogConfigBuilder()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
This is how I should use DialogConfigBuilder
DialogConfig config = new DialogConfig.DialogConfigBuilder<>()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
Pay attention to <> in the second case.
I have a class Zeitpunkt which implements a date with time and in addition a class Suchbaum which represents a binary search tree.
I want to use a Comparator-Object in Suchbaum to sort a tree by the day of Zeitpunkt, but when I want to create a Suchbaum object, it prints the named error.
Zeipunkt
public class Zeitpunkt<T> implements Comparable<T>
{
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) { ... }
#Override
public int compareTo(T o) {
if(o instanceof Zeitpunkt)
return vergleich((Zeitpunkt)o);
return 0;
}
...
}
Suchbaum
public class Suchbaum<T extends Comparable<T>> {
private class Element {
private T daten;
private Element links;
private Element rechts;
public Element(T t) {
daten = t;
links = null;
rechts = null;
}
}
private Element wurzel;
private Comparator<T> comp;
...
}
Testclass
public class BaumTest {
public static void main(String[] args) {
// error in the following line (IntelliJ underlines the first
// "Zeitpunkt"). Suchbaum<Zeitpunkt<?>> = ... doesn't work either..
// *Completely confused*
Suchbaum<Zeitpunkt> sb = new Suchbaum<>((Zeitpunkt z1, Zeitpunkt z2) -> {
if(z1.getTag() > z2.getTag())
return 1;
else if(z1.getTag() == z2.getTag())
return 0;
else
return -1;
});
}
}
Any ideas? (the other threads with this topic didn't help me out)
Seems that you don't want to make your Zeitpunkt class parametrized, you just want it to implement Comparable interface. So change it like this:
public class Zeitpunkt implements Comparable<Zeitpunkt> {
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) {
return 0;
}
#Override
public int compareTo(Zeitpunkt o) {
return vergleich(o);
}
}
Also you need to define a constructor in your Suchbaum class:
public Suchbaum(Comparator<T> comp) {
this.comp = comp;
}
I got this error when i try to run my code:
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at edu.ndhu.bm.healthow.HealThowConstant.<init>(HealThowConstant.java:91)
at edu.ndhu.bm.healthow.HealThow.main(HealThow.java:511)
i have searched for similiar answer but i still couldn't fix it. This must be something related to the conversion of data types but i do not know how to fix the problem.
I am new to Java programming so any help will be much appreciated. Thank you. and here's the code:
package edu.ndhu.bm.healthow;
import java.util.Properties;
public class HealThowConstant
{
public final int n;
public final int m;
public final int d;
public final int t;
public final double taux;
public final double etax;
public final double ax;
public final double bx;
public final double alphax;
public final double betax;
public final double qx;
public final double add_taux;
public final double tauUpperBoundx;
public final double lux;
public final double minlux;
public final double gux;
public final double mingux;
public final double tauy;
public final double etay;
public final double ay;
public final double by;
public final double alphay;
public final double betay;
public final double qy;
public final double add_tauy;
public final double tauUpperBoundy;
public final double luy;
public final double minluy;
public final double guy;
public final double minguy;
public final double tauw;
public final double etaw;
public final double aw;
public final double bw;
public final double alphaw;
public final double betaw;
public final double qw;
public final double add_tauw;
public final double tauUpperBoundw;
public final double luw;
public final double minluw;
public final double guw;
public final double minguw;
public final String nfetay;
public final int ant;
public final int iteration;
public final String parameter;
public final int fl;
public final int fu;
public final int pl;
public final int pu;
public final int cl;
public final int cu;
public final int rl;
public final int ru;
public final int Cl;
public final int Cu;
public final int ul;
public final int uu;
public final int al;
public final int au;
public final String scenario_generate;
public final int scenario;
public final int average;
public final int variance;
public final int stage;
public final double runtime;
public HealThowConstant(Properties properties)
{
n = Integer.parseInt(properties.getProperty("n"));
m = Integer.parseInt(properties.getProperty("m"));
d = Integer.parseInt(properties.getProperty("d"));
t = Integer.parseInt(properties.getProperty("t"));
taux = Double.parseDouble(properties.getProperty("taux"));
etax = Double.parseDouble(properties.getProperty("etax"));
ax = Double.parseDouble(properties.getProperty("ax"));
bx = Double.parseDouble(properties.getProperty("bx"));
alphax = Double.parseDouble(properties.getProperty("alphax"));
betax = Double.parseDouble(properties.getProperty("betax"));
qx = Double.parseDouble(properties.getProperty("qx"));
add_taux = Double.parseDouble(properties.getProperty("add_taux"));
tauUpperBoundx = Double.parseDouble(properties.getProperty("tauUpperBoundx"));
lux = Double.parseDouble(properties.getProperty("lux"));
minlux = Double.parseDouble(properties.getProperty("minlux"));
gux = Double.parseDouble(properties.getProperty("gux"));
mingux = Double.parseDouble(properties.getProperty("mingux"));
tauy = Double.parseDouble(properties.getProperty("tauy"));
etay = Double.parseDouble(properties.getProperty("etay"));
ay = Double.parseDouble(properties.getProperty("ay"));
by = Double.parseDouble(properties.getProperty("by"));
alphay = Double.parseDouble(properties.getProperty("alphay"));
betay = Double.parseDouble(properties.getProperty("betay"));
qy = Double.parseDouble(properties.getProperty("qy"));
add_tauy = Double.parseDouble(properties.getProperty("add_tauy"));
tauUpperBoundy = Double.parseDouble(properties.getProperty("tauUpperBoundy"));
luy = Double.parseDouble(properties.getProperty("luy"));
minluy = Double.parseDouble(properties.getProperty("minluy"));
guy = Double.parseDouble(properties.getProperty("guy"));
minguy = Double.parseDouble(properties.getProperty("minguy"));
tauw = Double.parseDouble(properties.getProperty("tauw"));
etaw = Double.parseDouble(properties.getProperty("etaw"));
aw = Double.parseDouble(properties.getProperty("aw"));
bw = Double.parseDouble(properties.getProperty("bw"));
alphaw = Double.parseDouble(properties.getProperty("alphaw"));
betaw = Double.parseDouble(properties.getProperty("betaw"));
qw = Double.parseDouble(properties.getProperty("qw"));
add_tauw = Double.parseDouble(properties.getProperty("add_tauw"));
tauUpperBoundw = Double.parseDouble(properties.getProperty("tauUpperBoundw"));
luw = Double.parseDouble(properties.getProperty("luw"));
minluw = Double.parseDouble(properties.getProperty("minluw"));
guw = Double.parseDouble(properties.getProperty("guw"));
minguw = Double.parseDouble(properties.getProperty("minguw"));
nfetay = properties.getProperty("nofactoryetay");
ant = Integer.parseInt(properties.getProperty("ant"));
iteration = Integer.parseInt(properties.getProperty("iteration"));
parameter = properties.getProperty("parameter");
fl = Integer.parseInt(properties.getProperty("fl"));
fu = Integer.parseInt(properties.getProperty("fu"));
pl = Integer.parseInt(properties.getProperty("pl"));
pu = Integer.parseInt(properties.getProperty("pu"));
rl = Integer.parseInt(properties.getProperty("rl"));
cl = Integer.parseInt(properties.getProperty("cl"));
cu = Integer.parseInt(properties.getProperty("cu"));
ru = Integer.parseInt(properties.getProperty("ru"));
Cl = Integer.parseInt(properties.getProperty("Cl"));
Cu = Integer.parseInt(properties.getProperty("Cu"));
ul = Integer.parseInt(properties.getProperty("ul"));
uu = Integer.parseInt(properties.getProperty("uu"));
al = Integer.parseInt(properties.getProperty("al"));
au = Integer.parseInt(properties.getProperty("au"));
scenario_generate = properties.getProperty("scenario_generate");
scenario = Integer.parseInt(properties.getProperty("scenario"));
average = Integer.parseInt(properties.getProperty("average"));
variance = Integer.parseInt(properties.getProperty("variance"));
stage = Integer.parseInt(properties.getProperty("stage"));
runtime = Double.parseDouble(properties.getProperty("runtime"));
}
}
This stack trace is saying that on line 91, you are using Integer.parseInt but you are passing in null into it. That is why this error is happening. You must pass in a String that represents an integer. You can't pass in null.
You either need to check for null and avoid passing it in, or make sure that line 91 always passes in non-null.
As Daniel Kaplan said, you are passing in a null value into Integer.parseInt which is causing the exception. The Javadoc for parseInt says that this will cause a NumberFormatException to be thrown:
Throws:
NumberFormatException - if the string does not contain a parsable integer
As you said in your comment, this is happening at t = Integer.parseInt(properties.getProperty("t")); The problem is that your properties variable is called and cannot find a property. Looking at the Javadoc for the java.util.Properties method public String getProperty(String key), emphasis mine:
Searches for the property with the specified key in this property
list. If the key is not found in this property list, the default
property list, and its defaults, recursively, are then checked. The
method returns null if the property is not found.
It seems like you want to avoid passing in a null to the Integer.parseInt method. You can do this is in different ways depending on how you want to model your class, but here are a few that you could do:
Do a null check before you do Integer.parseInt
Use the public String getProperty(String key, String defaultValue), that supplies a default if a property cannot be found. I.e., properties.getProperty("t", "15")