Initialising/Creating Objects through a constructor - java

Ok so I'm doing an assignment for my java coursets part I'm stuck at is :
"Implement an operation createparliamentMembers which will create the particular Parliament
with 80 members."
So i've already created the constructor with it's methods. This is how I wrote the operation to create the objects using the constructor.:
public static void createparliamentMembers(){
Member[] array = new Member[75];
for(int i = 0; i < array.length; i++)
{
if (i < 35) array[i] = new Member(i, "Blue");
else array[i] = new Member(i,"Red");
}
Legislator[] leg = new Legislator[3];
for (int i = 0 ; i < leg.length; i++){
leg[i] = new Legislator(i, "Impartial");
}
Leader[] lead = new Leader[2];
for (int t = 0; t < lead.length; t++){
if (t < 1) lead[t] = new Leader(1, "Red");
else lead[t] = new Leader(2, "Blue");
}
The problem is the arrays and objects only seem to exist in the operation for creating them and when I try running method of the objects created they don't work because the driver class doesn't recognize the arrays. On the other hand when I use this as just a normal part of the Driver for it runs fine and all methods of the objects work normally.
Edit: Ok so I'm still getting the same problem as before even though i initiliased them outside the createparliamentMembers();
The following code is the Driver im using to test the methods: It keeps saying there is a:
Exception in thread "main" java.lang.NullPointerException at Driver.main(Driver.java:11)
which is the code array[1].FlipCoin(); as im trying to use the method flipcoin from the created objects but it's not working.
public static void main(String [] args) {
Commands.createparliamentMembers();
array[1].FlipCoin();
}

Your arrays are only defined locally, which means they live and die with the method. When your method finishes, they get put out of memory.
The solution is to define these arrays as instance variables. By that I mean, you need to define the arrays for your class, and then use them in your method:
class someClass {
int[] myArray = new int[2];
private void someMethod() {
myArray[0] = 3;
myArray[1] = //whatever
}
}

You state in comment:
I do have a parliament class it's on it own and contains the methods and constructor for the members of the parliament. The above method was in a seprate class called Commands. I don't understand completely the "Can you add the members to a Parliament object as you create them?" The parliament isn't an object more se then a class containing a constructor and methods for parliament members i want to create.
Parliament isn't an object yet, but you should in fact create one, and in fact your instructions tell you just that: "which will create the particular Parliament with 80 members...". You will need to tell us more about your program's structure and your specific requirements, but I suggest:
First create a Parliament object in the createParliamentMembers method, and call it parliament.
Then create the members of parliament in that method.
As you create these members, add them to the Parliament object, parliament.
At the end of the method return the parliament variable.
This means that your createParliamentMembers method's signature must change so that rather than return void it should be written to return a Parliament object.
When calling the method in the main method, assign what it returns to a Parliament variable that is in the main method.

It looks like you are writing a factory method. Create a constructor for Parliament like this:
public Parliament(Member[] members, Legislator[] legislators, Leader[] leaders) {
// do whatever with what's passed in
}
Then change your method to return a Parliament object and in the method pass your initialized arrays into the Parliament constructor, like this:
// same code as your except the last line
public static Parliament createParliament(){
Member[] array = new Member[75];
for(int i = 0; i < array.length; i++)
{
if (i < 35) array[i] = new Member(i, "Blue");
else array[i] = new Member(i,"Red");
}
Legislator[] leg = new Legislator[3];
for (int i = 0 ; i < leg.length; i++){
leg[i] = new Legislator(i, "Impartial");
}
Leader[] lead = new Leader[2];
for (int t = 0; t < lead.length; t++){
if (t < 1) lead[t] = new Leader(1, "Red");
else lead[t] = new Leader(2, "Blue");
}
return new Parliament(array, leg, lead);
}

Related

Is there a way to loop execute a method while passing a different instance of a class to it each time?

My current code looks something like this:
public void myMethod()
{
instance1.myPanel.setVisible();
instance2.myPanel.setVisible();
instance3.myPanel.setVisible();
instance4.myPanel.setVisible();
//A bunch more
instance57.myPanel.setVisible();
}
Is there a ways to shorten it?
The Code below obviously doesn't work but gives you an idea of what I'm trying to do:
public void myMethod2(myClass instance1)
{
instance1.myPanel.setVisible();
}
int i = 1;
while(i <= 57)
{
myMethod2("instance" + i);
i++
}
In practice, this kind of problem is normally handled using some sort of collection, and its use will often fit naturally into the initialization of a program with a large number of objects. Rather than hand-writing the creation of 57 similar objects, one line at a time, you would create them in a loop, adding them to a collection as you do so.
A List implementation like ArrayList would be a good choice here, or one could simply use an array.
With a List:
/* During initialization of your program somewhere. */
List<MyClass> instances = new ArrayList<>();
for (int i = 0; i < 57; ++i) {
instances.add(new MyClass());
}
...
/* Later when you need to invoke a method: */
instances.forEach(instance -> instance.myPanel.setVisible());
You can build a list of your vars and just go through them:
List<ClassType> list = Arrays.asList( obj1, ob2, obj3 );
list.forEach( instance -> instance.myPanel.setVisible() );

Objects of an array is displaying an error "Java returned: 1" when using setters (or anything) with it

I'm very new to programming.
I have a main class and another class, myClass.
When I run the program there is an error in the main class.
It is supposed to be an array of objects and the loop is supposed to set/change/declare things for each object.
Code from the main class:
myClass[] myObj= new myClass[100];
for(int i = 0; i<amount;i++){
myObj[i].setF(sc.next());
myObj[i].setG(sc.next());
myObj[i].myMethod[0]=sc.nextInt();
myObj[i].myMethod[1]=sc.nextInt();
myObj[i].myMethod[2]=sc.nextInt();
}
error says line says "Java returned: 1" and the links redirect me to: <java classname="#{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true" jvm="${platform.java}">
In the myObj class there are no issues, and from what I can tell trough testing it, the error is specifically coming from myObj[i].
I can't figure out how to fix it though.
You're not initializing your array elements before using them. You would need to define a constructor for your class like this(Note that Java class names should always start with uppercase):
// With your current approach you would at least need to allocate memory for member array
public MyClass() {
this.myMethod = new int[3];
}
or
// You can also use a constructor like this
public MyClass(String f, String g, int[] methodArr) {
this.f = f;
this.g = g;
this.myMethod = methodArr;
}
Then you should be able to call it from your driver method like this:
Using No argument constructor:
for (int i = 0; i < amount; i++) {
myObj[i] = new MyClass();
myObj[i].setF(sc.next());
myObj[i].setG(sc.next());
myObj[i].myMethod[0] = sc.nextInt();
myObj[i].myMethod[1] = sc.nextInt();
myObj[i].myMethod[2] = sc.nextInt();
}
Using argument constructor:
for (int i = 0; i < amount; i++) {
int[] myMethodArr = new int[3];
String fInput = sc.next();
String gInput = sc.next();
myMethodArr[0] = sc.nextInt();
myMethodArr[1] = sc.nextInt();
myMethodArr[2] = sc.nextInt();
myObj[i] = new MyClass(fInput, gInput, myMethodArr);
}
In Java when you create an array, you are only creating an array of references. This means that your object instances are not automatically there.
The effect of this fact is that you have to create your array first, and then populate it with references to objects, which you also have to create. Here is how to do that:
myClass[] myObj= new myClass[100];
for(int i = 0; i<amount;i++){
myObj[i] = new myClass(); // here you populate the array with instances
myObj[i].setF(sc.next());
myObj[i].setG(sc.next());
myObj[i].myMethod[0]=sc.nextInt();
myObj[i].myMethod[1]=sc.nextInt();
myObj[i].myMethod[2]=sc.nextInt();
}

Accesing a static ArrayList from another class in Java

The ArrayList needs to be set to static. I created a getter method in the main class (CityMenuCreate).In the second class, I do call the method and when I try to create a for function, it doesn't recognize the list.
The method I created in the first class (CityMenuCreate)
public static ArrayList getCityList() {
return cityList;
}
The part of code I'm trying to call the method in the second class
CityMenuCreate.getCityList();
for(int i=0; i< **cityList.size();** i++) {
}
It gives me an error in the cityList.size();. Is there a syntax problem in the for function?
You're ignoring the return value of CityMenuCreate.getCityList(). You either need to save it to a local variable:
List cityList = CityMenuCreate.getCityList();
for (int i = 0; i < cityList.size(); i++) {
// code
}
Or just use it directly from that method:
for (int i = 0; i < CityMenuCreate.getCityList().size(); i++) {
// code
}
In the above example, you've declared your getCityList() method as static, not your Arraylist. Hence you cannot access your Arraylist in a static way. You either declare your Arraylist static or in your for loop you call the method like so:
for (int i = 0; i < CityMenuCreate.getCityList().size(); i++) {
//Your code goes here
}

Using Runnable to run a method by multiple threads

In my program, I want to create multiple threads in one of the methods where each thread has to run a specific method with a given input. Using Runnable, I have written this snippet.
class myClass {
public myClass() { }
public void doProcess() {
List< String >[] ls;
ls = new List[2]; // two lists in one array
ls[0].add("1"); ls[0].add("2"); ls[0].add("3");
ls[1].add("4"); ls[1].add("5"); ls[1].add("6");
// create two threads
Runnable[] t = new Runnable[2];
for (int i = 0; i < 2; i++) {
t[ i ] = new Runnable() {
public void run() {
pleasePrint( ls[i] );
}
};
new Thread( t[i] ).start();
}
}
void pleasePrint( List< String > ss )
{
for (int i = 0; i < ss.size(); i++) {
System.out.print(ss.get(i)); // print the elements of one list
}
}
}
public class Threadtest {
public static void main(String[] args) {
myClass mc = new myClass();
mc.doProcess();
}
}
Please note, my big code looks like this. I mean in one method, doProcess(), I create an array of lists and put items in it. Then I want to create threads and pass each list to a method. It is possible to define the array and lists as private class members. But, I want to do that in this way.
Everything seems to be normal, however, I get this error at calling pleasePrint():
error: local variables referenced from an inner class must be final or effectively final
pleasePrint( ls[i] );
How can I fix that?
The reason you are getting this error is straightforward and clearly mentioned - local variables referenced from an inner class must be final or effectively final. This is, in turn, because, the language specification says so.
Quoting Guy Steele here:
Actually, the prototype implementation did allow non-final variables
to be referenced from within inner classes. There was an outcry from
users, complaining that they did not want this! The reason was interesting: in order to support such variables, it was necessary to
heap-allocate them, and (at that time, at least) the average Java
programmer was still pretty skittish about heap allocation and garbage
collection and all that. They disapproved of the language performing
heap allocation "under the table" when there was no occurrence of the
"new" keyword in sight.
As far as your implementation goes, instead of using an array of list, I'd rather use a list of lists.
private final List<List<String>> mainList = new ArrayList<>();
You can create new lists and insert them into the main list in the constructor depending on the number of lists you want.
public ListOfLists(int noOfLists) {
this.noOfLists = noOfLists;
for (int i = 0; i < noOfLists; i++) {
mainList.add(new ArrayList<>());
}
}
You can then change your doProcess() method as follows:
public void doProcess() {
for (int i = 0; i < noOfLists; i++) {
final int index = i;
// Using Lambda Expression as it is much cleaner
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
pleasePrint(mainList.get(index)); // Pass each list for printing
}).start();
}
}
Note: I used an instance variable named noOfLists to (as the name suggests) store the number of lists I need. Something as follows:
private final int noOfLists;
To populate the list, you could do:
mainList.get(0).add("1");
mainList.get(0).add("2");
mainList.get(0).add("3");
mainList.get(1).add("4");
mainList.get(1).add("5");
mainList.get(1).add("6");
// And so on...
And you'll get the output something as:
Thread-0
1
2
3
Thread-1
4
5
6
Hope this helps :)
First to that, you will get a NullPointerException here:
ls[0].add("1"); ls[0].add("2"); ls[0].add("3");
ls[1].add("4"); ls[1].add("5"); ls[1].add("6");
Before, yo must instantiate the lists:
ls[0] = new ArrayList<>();
ls[1] = new ArrayList<>();
About the compiler error, try to define the array as final. Change:
List< String >[] ls;
ls = new List[2]; // two lists in one array
By:
final List< String >[] ls = new List[2]; // two lists in one array
This is because you can't access to non-final (or effectively final) variables from a local class.
'ls' is effectively final but probably, since you have defined it in two lines, the compiler is not able to notice that.

Class instance change another instance

The code is :
package classes;
public class Test {
private static double mutationRate = 0.5;
public static void main(String[] args) {
Population pop = new Population();
pop.initialise();
Population po = new Population();
po.getIndividusList().add(pop.getFittest());
po.getIndividusList().add(mutate(pop.getIndividusList().get(1)));
}
private static Chromosom mutate(Chromosom l) { // changer les couples d'interventions des parcs)
// loop through genes
Chromosom ch = new Chromosom();
for (int i = 0; i < l.size(); i++)
ch.put(i, l.get(i));
for (int i = 0; i < ch.size(); i++) {
double alea = Math.random() * 13;
int moisIntervention1 = (int) alea;
Intervention interv1 = new Intervention(1, moisIntervention1);
ch.get(i).modInterventions(ch.get(i).intervention2(interv1));
}
return ch;
}
}
The problem is that I did not change the instance pop but when I change the other instance po, pop changes too.
java pass by value.
when you call this mutate(pop.getIndividusList().get(1))
you are sending pop's instance, so it will get change.
Supose pop.getIndividusList().get(1) return String varibale do this way
String var=pop.getIndividusList().get(1);
then call mutate(var)
I'm unsure about whether I understood the problem, but I think that you mean that when you alter the items in Population po, the items in Population pop mirror those changes.
That is, indeed, the expected behavior of your code: to populate po, you are adding items from pop - (pop.getFittest, pop.getList.get(1) ).
But the individuals are, I believe, instances of objects, so add/remove and similar operations work with references to the objects, and not with copies of them. Therefore, as you have 2 references to the same obj, any change is mirrored.
IF you want to create a copy, you should add to po a new object with the same state, either by creating a constructor that takes another instance as parameter, implementing a copy method, or something similar.
It should be something like this:
Population po = new Population();
Individual fittest = pop.getFittest();
Individual poCopy = new Individual();
//ADD CODE HERE TO COPY ALL THE FIELDS FROM fittest TO poCopy
//....
po.getIndividusList().add(poCopy);

Categories