Can anyone help me with this java code?
I have two classes and need to create a set that can store instances of the other class. here is the sample I managed to "commit" :)
Class A
public Class Rabbit {
private String age;
//constructor for instance of Rabbit <br>
public Rabbit(String rabAge) {
super();
this.age = rabAge;
}
now class B:
public class ManyRabbits {
private Set <String> setOfRabbits;
now this method should create a new instance of the Rabbit and add it to the set represented by variable setOfRabbits
public void addRabbit (String age)` {
//and I don't know what should go next...something like: `
Rabbit r1 = new Rabbit("10");` <br>
setOfRabbits.add(r1);
}
You need to change your set declatation :
private Set<Rabbit> setOfRabbits;
And you also need to ovweride those two method in order to never insert twice the same object in the set.
#Override
public int hashCode() {
// Your own implementation
return ...;
}
#Override
public boolean equals(Object o) {
// Your own implementation
return ...;
}
your ManyRabbits calss should be like this
public class ManyRabbits
{
private Set<Rabbit> setOfRabbits = new HashSet<Rabbit>();
public void addRabbit (String age)
{
Rabbit r1 = new Rabbit(age);
setOfRabbits.add(r1);
}
}
public class Rabbit {
private String age;
//constructor for instance of Rabbit
public Rabbit(String rabAge) {
super();
this.age = rabAge;
}
// more methods if necessary
}
In ManyRabbits:
public class ManyRabbits {
private Set <Rabbit> setOfRabbits = new HashSet<>();
public void addRabbit (String age) {
Rabbit r1 = new Rabbit(age);
setOfRabbits.add(r1);
}
// more methods if necessary
}
Use it by calling something like
ManyRabbits manyRabbits = new ManyRabbits();
manyRabbits.addRabbit("10");
manyRabbits.addRabbit("20");
manyRabbits.addRabbit("30");
Say:
Set<Rabbit> setOfRabbits = new HashSet<>();
setOfRabbits.add(new Rabbit());
When the Set will be keeping track of an unknown quantity of an object, I typically try to instantiate with an unnamed instance. This would work great for adding to a listener so that you could, say, add a new Rabbit every time the user clicks.
In this way, you could add however many Rabbit object you want. Try:
for(i = 0; i < 10; i++) {
setOfRabbits.add(new Rabbit());
}
You may see this in older versions of Java:
Set<Rabbit> setOfRabbits = new HashSet<Rabbit>();
but it is no longer necessary
Related
everyone! I'm total noob in Java and in programming in general and I want to implement CarBrand class with its' inner Model class (let there be no more than 4 models for each brand). For example:
public class CarBrand {
public String brand;
public Model[4] models;
public int curIndex = 0;
public CarBrand(String name) {
brand = name;
Model[] models = new Model[4];
}
public class Model {
public String modelName;
public Model(String name) {
modelName = name;
models[curIndex] = this;
curIndex = curIndex + 1;
}
}
}
I want to make new instance of CarBrand and its new Model (and add this model into models array of new instance of CarBrand) this way:
public class App {
public static void main(String args[]) {
CarBrand subaru = new Auto("Subaru");
CarBrand.Model legacy = subaru.new Model("Legacy");
System.out.println(subaru.models[0]);
}
}
But unfortunately running App finishes with error:
Exception in thread "main" java.lang.NullPointerException: Cannot store to object array because "<parameter1>.models" is null
What is the reason behind that? Is there a way to add a new model in brand's models array? I suppose, the object wasn't created yet, that's why there is an error. How far am I from the truth?
Your syntax is generally incorrect: you would need
public Model[] models; // not Model[4]
public int curIndex = 0;
public CarBrand(String name) {
brand = name;
models = new Model[4]; // not Model[]
}
I wrote some classes in Java but when I run the program I receive the error "ArrayIndexOutOfBoundsException", the incriminate class is this:
public class Bank {
private String name;
private int maxbankaccount;
private int activebankaccount;
private String radice = "IT8634";
private Conto[] bankaccount = new Conto[maxbankaccount];
public void addconto(String cf) {
bankaccount[activebankaccount] = new Conto(radice + activebankaccount , cf);
activebankaccount++;
}
public Bank(String name, int maxbankaccount) {
this.name = name;
this.maxbankaccount = maxbankaccount;
}
}
I wrote a tester class to test :
public class TestBank {
public static void main (String[] args) {
Bank b1 = new Bank("Fidelity", 10);
b1.addconto("PROVA");
}
}
Since I didn't seem to have made logical errors using the array I debugged, I realized that in the creation of the array of objects the maxbankaccount variable isn't 10 (value passed in Test) but as default value (0),then I tried passing 10 directly and it works good. Why is not the value 10 of maxbankaccount passed but 0?
private Conto[] bankaccount = new Conto[maxbankaccount];
This initialization takes place before the rest of the constructor runs.
Move it into the constructor:
public Bank(String name, int maxbankaccount) {
this.name = name;
this.maxbankaccount = maxbankaccount;
this.bankaccount = new Conto[maxbankaccount];
}
You have indeed made a logical error. The array bankaccount is getting initialized when the class is instantiated and is always 0.
Move it into the constructor and initialize it.
public Bank(String name, int maxbankaccount) {
/* ... */
this.bankaccount = new Conto[maxbankaccount];
}
Further more than the issues that are in the other answers, this
private int activebankaccount;
does not initialize the variable activebankaccount
So in:
public void addconto(String cf) {
bankaccount[activebankaccount] = new Conto(radice + activebankaccount , cf);
activebankaccount++;
}
you are using an uninitialized vale as index of the array bankaccount
This is a continuation from what I was working in Passing 1 to many parameters of same object type
I've gotten good feedback on that , I believe i have the improved the design . The whole code is at https://github.com/spakai/flow_input_builder
The requirement is simple : -
I need to build a set of input for different workflows using 1 or more outputs from previous workflows
I have a set of interfaces
public interface SwfInput {
}
public interface SwfOutput {
}
public interface Workflow<I extends SwfInput, O extends SwfOutput> {
public O execute(I input);
}
public interface Builder<I extends SwfInput> {
public I build();
}
Now , Say I have 3 flows which gets executed in sequence FlowA->FlowB->FlowC
FlowC needs mandatory output from FlowB but only optionally from FlowA
so I have a implementation for FlowCBuilder
public class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowBOutput mandatoryflowBOutput;
private FlowAOutput optionalflowAOutput;
public FlowAOutput getOptionalflowAOutput() {
return optionalflowAOutput;
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
this.optionalflowAOutput = optionalflowAOutput;
return this;
}
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
this.mandatoryflowBOutput = mandatoryflowBOutput;
}
#Override
public FlowCInput build() {
FlowCInput input = new FlowCInput();
input.setMandatoryFromFlowB(mandatoryflowBOutput.getOutput1FromB());
if (optionalflowAOutput != null) {
input.setOptionalFromFlowA(optionalflowAOutput.getOutput2FromA());
}
return input;
}
}
one test i have written shows an example usage
FlowBOutput mandatoryflowBOutput = new FlowBOutput();
mandatoryflowBOutput.setOutput1FromB("iNeedThis");
FlowAOutput optionalflowAOutput = new FlowAOutput();
FlowCInput input = new FlowCInputBuilder(mandatoryflowBOutput)
.setOptionalflowAOutput(optionalflowAOutput)
.build();
I have not used static inner class for the Builder pattern.
Any suggestions are welcomed.
You should use static inner class. The key point of using this approach is that, the inner can directly access private properties of the object being constructed. This helps eliminating duplicated code since the builder does not need to maintain a long list of temporary state for the constructing. So, your code can be rewritten like this:
public class FlowCInput {
private int output1FromB; // suppose that it is int
private String output2FromA; // suppose that it is String
private FlowCInput() { }
//...
public static class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowCInput result;
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
result = new FlowCInput();
// output1FromB is private but still accessed from here
result.output1FromB = mandatoryflowBOutput.getOutput1FromB();
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
// same for output2FromA
result.output2FromA = optionalflowAOutput.getOutput2FromA();
return this;
}
#Override
public FlowCInput build() {
return result;
}
}
}
As you see, the builder now holds only a FlowCInput object, it does not unnecessarily hold mandatoryflowBOutput and optionalflowAOutput as before.
I am trying to apply varargs. I have declared a method which requires an indefinite amount of variables like this:
private Subject carMonitor;
public AdvancedMonitor(Subject ... carMonitors){
for (Subject carMonitor : carMonitors){
this.carMonitor = carMonitor;
carMonitor.registerObserver(this);
}
}
However, when I try to call it in my main method, I am not able to use anything other than one argument:
BigCar bigCar = new BigCar();
SmallCar smallCar = new SmallCar();
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
Only the second one works. Why is this?
Is it related to my interface?
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
big car interface -- small car is pretty much the same for now :
public class BigCar implements Subject {
private ArrayList observers;
private int state;
public BigCar(){
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
int i = observers.indexOf(o);
if (i >= 0){
observers.remove(i);
}
}
public void notifyObservers(){
for (int i = 0; i < observers.size(); i++){
Observer observer = (Observer)observers.get(i);
observer.update(state);
}
}
public void stateChanged() {
notifyObservers();
}
public void setState(int state){
this.state = state;
stateChanged();
}
}
I write following code:
public class Test {
public static class AdvancedMonitor {
private String carMonitor;
public AdvancedMonitor(String... carMonitors) {
for (String carMonitor : carMonitors) {
this.carMonitor = carMonitor;
System.out.println(this.carMonitor);
}
}
}
public static void main(String[] args) {
String bigCar = "bigCar";
String smallCar = "smallCar";
System.out.println("step 1");
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
System.out.println();
System.out.println("step 2");
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
System.out.println();
System.out.println("step 3");
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
}
}
And I have following result:
step 1
step 2
bigCar
step 3
bigCar
smallCar
In my opinion, all correct. What is wrong in your case? Do you use logging or System.out.println to debug your problem? It's look like your problem isn't with Java varagrs, but you have some exception in carMonitor.registerObserver(this).
P.S. Also, you understand that every AdvancedMonitor has only a one varible carMonitor? And using new AdvancedMonitor(bigCar, smallCar); in result you have AdvancedMonitor only with smallCar in private String carMonitor;?
P.P.S. Also bad idea to use this in construstor, because object isn't really create when running construstor.
Actually the Constructor works.
Please check these statements:
SmallCar and BigCar both implements Subject
class AdvancedMonitor implements Observer
AdvancedMonitor doubleAdvancedDisplay is not declared several times but in your code it is. It should be smth like:
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
I hope it'll help you
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx