I am writing a program dealing with subnets.
In simpleIPaddress.class line 315, the object Ted's fullSubnetAddress = "111.111.111.111".
In simpleIPaddress.class line 317, the object Ted's fullSubnetAddress changes for some reason I can not figure out. It changes to the as textAddress the field variable for the class. textAddress is generated from the program earlier in the code when the simpleIPaddress address is initially created from user input.
After the first time the for loop is executed, Ted is changed permanently for the rest of the for loop.
In the code I am slowly populating an array.
SubnetItem ted = new SubnetItem(subnetNumber, fullSubnetAddress, fullStartHost,
fullEndHost, fullBroadcastAddress);
this.subnetArray = new SubnetItem[totalSubnets];
for (int i = 0; i < subnetArray.length; i++)
{
this.subnetArray[i] = ted; // line 315
this.subnetArray[i].setSubnetNumber(i);
System.out.println(ted.toString()); // line 317
calculateStartingAddress(i);
System.out.println(ted.toString());
System.out.println(subnetArray[i].toString());
}
Here is the full code if that is needed.
You create only one SubnetItem object, then inside the for loop you repeatedly modify that single object while assigning every element of the array to point at the object. By the time the loop is over, you have an array full of pointers to the same object, now having the last value assigned to it.
If you want every array element to have a different value, you need to create a separate object for each one. That is as simple as moving the SubnetItem ted = new SubnetItem(...); line down a few lines so that it is inside the for loop.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Please can you explain to me if we want to add an element to a the end of a preexisting array how is it properly done.
I am having difficulty understanding the Littler class specifically the add method.
I understand that "Puppy[] temp = new Puppy[this.puppies.length + 1];"
We have a new array that is one greater in length than the puppies array (instance variable). "temp[i] = this.puppies[i];" assigns all the elements from the puppies array to the temp based on the indexes.
My confusion lies with line: temp[this.puppies.length] = puppy;
1.) What exactly is happening here?
In my mind I think that we are reassigning the last index position of this.puppies.length to the puppy parameter.
2.) Will that +1 (one size bigger) that was made, the extra index of the temp array on the line
"Puppy[] temp = new Puppy[this.puppies.length + 1];"
remain blank?
3.) Does "this.puppies = temp;" represent a shallow copy?
4.) What is this process called of making a bigger array and adding an object, do we have to do it every time (create an array one bigger).
5.) What happens if we don't, is there a situation where we don't have to make one bigger, or need a temp array? (I am just confused as to why we need it).
6.) What does an object of the class type mean? What does "private Puppy[] puppies;" mean exactly?
7.) Please can you help me decipher this code so I can understand. Especially with a hypothetical example if this.values.length was an array of a size of 5 elements (index 0-4).
//Class where add actions taking place
public class Litter {
private Puppy[] puppies;
public Litter() {
this.puppies = new Puppy[0];
}
public void add(Puppy puppy) {
Puppy[] temp = new Puppy[this.puppies.length + 1];
for (int i = 0; i < puppies.length; i++) {
temp[i] = this.puppies[i];
}
temp[this.puppies.length] = puppy;
this.puppies = temp;
}
}
First and foremost - arrays indices are 0 based. If you have an array of size 10, the valid array indices are from 0 to 9.
temp[this.puppies.length] = puppy
This stores the reference to some Puppy object (puppy) as the last element of the array. (since the length of temp is puppies.length + 1)
Will that +1 (one size bigger) that was made, the extra index of the temp array on the line [..] remain blank
No. The above assignment was made to the last element as arrays use 0-based indexing.
Does "this.puppies = temp;" represent a shallow copy?
No new object is created. After the assignment, both variables, this.puppies and the Puppy array (temp), point to the same object on the heap.
What is this process called of making a bigger array and adding an object, do we have to do it every time (create an array one bigger).
There is no general name for this. It is done here to add a new element to the array. Generally, to avoid this (often), a new array of double the size would be created.
What happens if we don't, is there a situation where we don't have to make one bigger, or need a temp array? (I am just confused as to why we need it).
Since arrays cannot be resized, you have to create a bigger array if you want to add a new object.
What does an object of the class type mean? What does "private Puppy[] puppies;" mean exactly?
puppies is an object that holds an array of Puppy objects.
Please can you help me decipher this code so I can understand. Especially with a hypothetical example if this.values.length was an array of a size of 5 elements (index 0-4).
This method is to add a new Puppy to the existing ones. Since arrays cannot be resized dynamically, it creates a new array(temp) and adds all the existing puppies. To accommodate a new Puppy, the created array size is one greater than the existing puppies. Then, it adds the passed Puppy instance as the last element of the array. The last line this.puppies = temp assigns the reference of the created array to the instance variable that points the puppies array.
In the snippet of code below, I am attempting to write the contents of the stocks2 ArrayList into the stock_train.csv file. I am employing a for-loop which should loop through every element of the stocks2 ArrayList (the debugger indicates that the size of the stocks2 ArrayList is 2955).
However, I am tracking how many lines of data are actually getting written to the file with the variable r. At the end of the for-loop's runtime, r's value is only 390. I have reviewed this code thoroughly and am struggling to find the issue as to why more than 80% of my data is not getting allocated to the file. (My stock_train.csv file only shows 390 lines of data, rather than 2955). Are there any memory allocation or syntax issues that are preventing this for-loop from writing all of stock2's data to the csv file? Thanks in advance for your time.
CSVWriter cd = new CSVWriter(new FileWriter("src/in/stock_train.csv"), ',', CSVWriter.NO_QUOTE_CHARACTER);
int r=0;
int dd=0; // Tracker variables
for(int g=0; g<stocks2.size(); g++) {
Stock q = stocks2.get(g); // stocks2: size = 2955
String[] temp2 = new String[4];
if(q.getTimestamp().startsWith("a")) {
dd++; // dd: 1
break; // This code is included to neglect any data whose timestamp begins with 'a'. As evidenced by the value of 'dd', it only happens once.
}
temp2[0] = q.getTimestamp();
temp2[1] = Double.toString(q.getPrice());
temp2[2] = Double.toString(q.getVWAP(pv,v));
temp2[3] = Integer.toString(q.getStatus()); // Data I want allocated to the "stocks_train.csv" file
r++; // r: 390
System.out.println(g + " " + temp2);
cd.writeNext(temp2);
}
cd.close();
/* Comments depict values of variables after the for-loops run-time based on debugger information */
Your comment suggests that you want to skip an entry, if the corresponding timestamp starts with an "a". You actually use the break; keyword, which terminates the loop. This also explains why dd has a value of exactly 1.
What you want is a continue; instead of the break;. This has the effect that program execution continues with the next iteration of the loop.
I am having a weird issue with java list. Please see the code below:
for ( int i=0; i < tripList.size(); i++ ) {
ModeChoiceTrip trip = tripList.get(i);
int newUniqueId = tripListIds[trip.uniqueId];
int newLinkedId = trip.linkedId >= 0 ? tripListIds[trip.linkedId] : -1;
int jointTripNum = trip.linkedId >= 0 && trip.tourType != TourTypes.SPECIAL_EVENT ? jointTripListIds[trip.linkedId] : 0;
trip.uniqueId = newUniqueId;
trip.linkedId = newLinkedId;
trip.jointTripNum = jointTripNum;
}
In the above code, the values in tripList seem correct but after executing a few iterations (up to i = 6), the values in tripList changes for all the positions.
I cannot provide the whole source code here but showing the snippet of the code where I have an issue.
I found that there are some duplicate trips in tripList. When one of the trips is changed, the copy of it (located at different position) is also changed.
I am guessing this piece of code is executed by multiple threads, Then there is every chance that List could be modified by another thread while this loop is going on.
you could try synchronizing the loop and see if issue gets resolved.
Also, you could try using for-each loop instead of the loop with counter.
for (ModeChoiceTrip trip : tripList) {
.....
}
The issues was the duplicate values in the list. Thus, when I update a value in list the copy to that value changes as well
You set the unique id to -1. So if the trip list id comes in as -1, you grab the index like tripListIds[-1]; which might be the second to the last item in the list.
I have an ArrayList which takes an object.
Handler.java
public ArrayList<LinkedInAccountObject> getAllLinkedInUsersFromDatabase(){
LinkedInAccountObject lao = new LinkedInAccountObject();
counter++;
lao.setAccountId(rs.getLong("account_id"));
lao.setLinkedInAccountId(rs.getString("linkedin_account_id"));
lao.setParentId(rs.getLong("parent_id"));
lao.setFirstName(rs.getString("first_name"));
lao.setLinkedInAccountId(rs.getString("linkedin_account_id"));
lao.setEmail(rs.getString("email"));
lao.setAccessToken(rs.getString("access_token"));
lao.setExpiresOn(rs.getLong("expires_on"));
laoarray.add(counter, lao);
}
My PageLoader.java uses this object to set values
ArrayList<LinkedInAccountObject> laoarray = lndb.getAllLinkedInUsersFromDatabase();
for (LinkedInAccountObject lao : laoarray) {
LinkedInPageObject lpo = new LinkedInPageObject();
lpo.setCompanyID(lao.getParentId());
lpo.setComment(lao.getComment());
//lpo.setDescription(obj.getString("description"));
//lpo.setTitle(obj.getString("title"));
}
But im unable to use the lao object to get the details, getting an null pointer.
when i print the lao object, it gives the result as below,
array objects[null, LinkedInAccountObject [accountId=xxx,
parentId=xx, expiresOn=xxx]]
I would suggest that you replace your loop in the second code with the following:
Iterator<LinkedInAccountObject> iterator = laoarray.iterator();
while(iterator.hasNext()){
LinkedInAccountObject lao = iterator.next()
LinkedInPageObject lpo = new LinkedInPageObject();
lpo.setCompanyID(lao.getParentId());
lpo.setComment(lao.getComment());
//remaining of your code.
}
EDIT
From all the comments that have been posted here I feel that you have initialised the counter variable as 0. In your method getAllLinkedInUsersFromDatabase() you are looping through a loop using rs.hasNext(). Now if this is correct, Then when the first data is being stored, your method creates a new instance of LinkedInAccountObject in lao. Then it goes on to increment counter by 1. So in this case counter was 0 now it becomes 1.
After all your code that you uploaded being executed in the last line it executes laoarray.add(counter, lao);. Here counter being at 1 adds the lao object to the laoarray at position index 1, leaving position index 0 as null. Then it repeats till the end of the ResultSet. This means if your rs variable returned 10 rows, they would be added to laoarray in indices 1 to 10 with 0 index being null.
You could verify if this is happening or not by simply System.out.println("laoarray length = "+laoarray.size()); in your 'PageLoader.java' after you have initialised the laoarray variable.
If this is correct then you could remove the counter++; in the method getAllLinkedInUsersFromDatabase() from its present location and set it after laoarray.add(counter, lao); as shown below:
LinkedInAccountObject lao = new LinkedInAccountObject();
//counter++; remove it from here.
lao.setAccountId(rs.getLong("account_id"));
lao.setLinkedInAccountId(rs.getString("linkedin_account_id"));
lao.setParentId(rs.getLong("parent_id"));
lao.setFirstName(rs.getString("first_name"));
lao.setLinkedInAccountId(rs.getString("linkedin_account_id"));
lao.setEmail(rs.getString("email"));
lao.setAccessToken(rs.getString("access_token"));
lao.setExpiresOn(rs.getLong("expires_on"));
laoarray.add(counter, lao);
counter++;//place it here
Does you counter start at -1? You do counter++ before adding to the arraylist.
This would mean that the first entry is never filled.
You could edit the code to start at index 0, or in the for loop check if the lao isen't null before handeling it.
This code doesn't seem complete but my guess is that you modify counter before adding the item so if you have an array and start with counter = 0 you add the first element to position 1 and position 0 remains null.
Make it:
LinkedInAccountObject lao = new LinkedInAccountObject();
.... fill object values ......
laoarray.add(counter, lao);
counter++;
I am trying to do check if an array is full and print out to the user he is unable to enter more books.
static Object[][] books=new Object[2][];
I am asking 3 values from the user and am storing to another array called "row".
Object[]row=new Object[3];
After that i loop through the books array and check if it has a null value inside of it and add the "row" array with the given values of the user.
the problem am having is i cant give any feedback if books array is full after entering two rows of values.
boolean empty=false;
while(empty==false){
for (int i = 0; i < books.length; i++) {
if(books[i]==null){
books[i]=row;
empty=true;
break;
}
}
}
Why not having a variable
int bookCounter = 0;
which you can increase/decrease everytime you add/delete books and then just check it against your max number of books (which I assume is books.length)
In this way you don't need to loop over the array, which is not efficient.
There is no need for the while loop. After the for loop ends, check your empty variable that you're already setting. If it's false, then give your feedback to the user.
Arrays are always full. Even each element is null. If you initialize it with the size of 10, then JVM will alocate memory and fill the all the arrays positions with default value. What is: 0 for primitives numbers and char type, false for primitive boolean type and null for Objects.
So, your code won't work with a int[] for instance. Because there won't exist any null element.
That's why you dont have a count() method... You can create a method that is named countNotNull(). But you'll need to interate for all the array long.
The best solution is to use a variable to count when you add/remove itens form array. As
Guillermo Merino said.