I seem to have a frustrating problem - an element of my arraylist is overwritten. I have looked at many posts in many forums, but I have not managed to solve it. :chomp:
In my program (which is actually a FBDK function block algorithm implemented in Java), I want to store the data of an input variable (PART) into an element of an out variable array (PART_array). This process will happen multiple times (with the occurence of an event) and must thus store the variable in several array elements.
The problem is that the elements of PART_array are overwritten by the last entry. For instance, for the first event occurence, PART_array[] = ["1"," "," "," "," "," "]. Then, with the second occurence, instead of PART_array[] = ["1","2"," "," "," "," "], I find PART_array[] = ["2","2"," "," "," "," "] - thus showing the overwrite. I have realised that overwrite already occurs with the storage to PART_ARRAY ArrayList. I thought that by reinitializing (p = new Part()) the problem would be solved...obviously not.
Any help in solving this problem will be GREATLY appreciated! The code is as follows:
public class STORE_TO_ARRAY extends fb.rt.FBInstance {
public ArrayList<Part> PART_ARRAY = new ArrayList<Part>();
Part p = new Part();
/** The default constructor. */
public STORE_TO_ARRAY() {
super();
}
/** ALGORITHM REQ IN Java*/ -- a method called in the program
public void alg_REQ() {
int ct = 0;
ct = current_task;
if (ct <= NumOfTasks) {
//write received input data to output variable array elements
//this is where the problem occurs!!!!
p.setPart(PART); //set value of Part
PART_ARRAY.add(ct-1,p); //adding to arraylist
Part p = new Part(); //trying to reinitialise the object
}
}
}
The class file for Part is as follows:
public class Part {
WSTRING part;
void setPart(WSTRING part) {
this.part = part;
}
WSTRING getPart() {
return part;
}
}
The below code creates a local variable (which, in the following line, goes out of scope and disappears before it is used), rather than assigning the class variable with a new value (which I'm assuming is what you're trying to do).
Part p = new Part(); //trying to reinitialise the object
Try replacing it with
p = new Part(); //trying to reinitialise the object
On a side note, a decent IDE (like NetBeans) should give you a warning about creating a local variable which hides a class variable.
Related
This question already has answers here:
Java: how to initialize String[]?
(11 answers)
Closed 12 months ago.
I've already created the whole code, but i don't know how to add a String to a String array.
here's my code:
**CandidateDAO candidatedao = new CandidateDAO();
String fill = null;
CandidateReport[] candidatesReports = candidatedao.getAllCandidates();
String [] newArray = ;
for(int i = 0; i < candidatesReports.length; i++) {
fill = candidatesReports[i].getCandidateId() + ":" + this.calculateGrade(candidatesReports[i]);
}
return newArray;*****
String [] newArray = ;
This is obviously wrong. To create an array of any type, you need to first instantiate it correctly. To do this, you need to set its size. The reason why you need to set its size is because arrays are allocated in memory in contiguous locations. This means that each index location is right next to another.
String [] newArray = new String[SOME_SIZE];
The SOME_SIZE is a value based on whatever you need. In your case, you have another array, candidatesReport, that could be used to determine the size (length) of your given array.
String [] newArray = new String[candiatesReport.length];
Now that is done, you need to set the value in the array.
newArray[i] = ...;
For you, this is done inside the loop...
for(int i = 0; i < candidatesReports.length; i++) {
newArray[i] = candidatesReports[i].getCandidateId() + ":" + this.calculateGrade(candidatesReports[i]);
}
UPDATE:
This problem is mainly to display some information contained in an array of CandidateReport objects by collecting data from each instance and concatenating it as a String. Not knowing about the internals of the aforementioned class, I believe this problem is better served by overwriting the Object's class toString() method in the CandidateReport class, so when objects of this type are printed, the output comes the way we want it. Otherwise, every class that wishes to display CandidateReport contents, it will have to repeat this same code over and over again. So here is a simple case for overriding toString() method.
public class CandidateReport {
// rest of code omitted
#Override
public String toString() {
return candidateId + ":" + grade;
}
}
If the grade needs to be calculated, you will be better off putting that logic in a utility class where you could call some static method to return the calculation. For example:
return candidateId + ":" + CalculatorUtilities.calculateGrade(grade);
The point of the matter is that each class should override the Object#toString() method to provide a default string representation of objects of a given type. If you do this, you won't need the String array at all. But, if you still feel it is necessary to capture this data in an String array, your code will be much simpler because of the overridden toString() method.
for(int i = 0; i < candidatesReports.length; i++) {
newArray[i] = candidatesReports[i].toString();
}
I'm trying to get the next value in a specific arraylist every time a user presses a button (using Swing).
This is my attempt at it:
private void BNextActionPerformed(java.awt.event.ActionEvent evt) {
int i = 0;
Parse p = new Parse();
temp = p.getTemp();
temp2 = p.getTemp2();
temp3 = p.getTemp3();
if (CBUniversities.getSelectedIndex() == 0) {
LNumStudents.setText("Number of students: " + temp);
Student s = p.getMacList().get(i+1);
jTextField2.setText(s.getFirstName());
TLastName.setText(s.getSurName());
jTextArea1.setText(s.getAddress());
i++;
}
}
Where Parse is a class, containing getter methods for 3 integerstemp,temp2,temp3, and a getter for an ArrayList.
Student s is an object of the Student class, where every student has a firstname, surname and address (initialized in a constructor).
When this if statement is executed it displays a students info in the specified fields, however, this only works for the first two students. After that, the i value never seems to increase?
I tried to place a println check to see it's value during the if statement, but it only changes once, oddly enough.
I also tried to make this into a for loop, yet the value again only seems to change once (of i).
Parse has this getter method I'm using
public ArrayList<Student> getMacList() {
return mac;
}
Also CBUniversities is a variable as such:
private javax.swing.JComboBox CBUniversities;
I'm not sure what's gone wrong here, any ideas?
You declared i within the scope of a method, so every time your method executes it reinitializes i.
Instead, declare an instance variable by putting private int i = 0; outside of your method, but still within the class scope.
I've a problem. I want to fill an array with objects containing different Informations.
here is my loop
public FileRecord [] calcPos() throws IOException{
for (int i = 0; i < getEFSFATmaxRecords(); i++){
int blockNumber = i/5;
int recordOffset = i%5;
pos = (recordOffset*100+(getFsatPos() + 512 + 512*blockNumber));
FileRecord rec = new FileRecord(pos,getHeader());
array = new FileRecord[header.getMaxFileRecords()];
array[i] = rec;
System.out.println("FileName: " + array[i].getFileName());
}
return array;
}
It should make different objects of FileRecord. The position depends on the running variable i. t
Then the loop stores everything in the array and returns the array. Ive declared array as a global variable in this calss so I thought the changes inside the loop would directly affect the global array. But it doesnt work. what I'm doing wrong?
Within the array you are doing:
array = new FileRecord[header.getMaxFileRecords()];
This will re-create the array every interation and you'll lose the records stored in it.
You'll need to do this before the loop
You are re initializing your array in every iteration. Below is a correct version of the code you want:
public FileRecord [] calcPos() throws IOException{
FileRecord[] array = new FileRecord[header.getMaxFileRecords()];
for (int i = 0; i < getEFSFATmaxRecords(); i++){
int blockNumber = i/5;
int recordOffset = i%5;
pos = (recordOffset*100+(getFsatPos() + 512 + 512*blockNumber));
FileRecord rec = new FileRecord(pos,getHeader());
array[i] = rec;
System.out.println("FileName: " + array[i].getFileName());
}
return array;
}
As vogel says if the header.getMaxFileRecords() changes within the loop then your array may run out of bound.
Solution: An ArrayList should work.
The problem is that you do:
array = new FileRecord[header.getMaxFileRecords()];
INSIDE the method every time it is invoked (in fact, inside the loop!).
This way, you are "setting" a new FileRecord[] object to the variable (and even worse, this happens many times in your method as the initialization is done in the loop).
Each time this initialization happens, the variable "points to the new FileRecord[] object allocated in memory. The Object that was "pointed to" by array before is not used anymore, and will be destroyed, the when is responsibility of the garbage collector.
(http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx).
In simple words, you are "recreating" the array again and again inside your loop.
Initialize the object only ONCE before using it in your method (for example in class constructor or in main, before using it in a sense).
Generally, I suggest that you don't use global variables. Search more on class encapsulation, a very important Object-Oriented Programming principle:
(http://www.tutorialspoint.com/java/java_encapsulation.htm).
I came across this code that says
new Class_Name(); // (i)
Now, normally I see the result of the new statement assigned to a variable:
Class_Name n = new Class_Name();
And n reference to the object created. What really happens when the (i) is called? And why would anyone want to do it? What are the uses for it?
CODE
class Tree {
int height;
Tree() {
print("Planting a seedling");
height = 0;
}
Tree(int initialHeight) {
height = initialHeight;
print("Creating new Tree that is " +
height + " feet tall");
}
void info() {
print("Tree is " + height + " feet tall");
}
void info(String s) {
print(s + ": Tree is " + height + " feet tall");
}
}
enter code here
public class Overloading {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
Tree t = new Tree(i);
t.info();
t.info("overloaded method");
}
// Overloaded constructor:
new Tree();
}
}
What really happens when the (i) is called
The below line of code creates an object of type Class_Name and since it is not referred by any reference variable , it dies immediately.
new Class_Name();
This way you can create an object of that class , and invoke methods on it without assigning it to a reference. This you will do when you need that object only once in your code and don't want to unnecessarily keep a reference to it . The anonymous object is created and dies instantaneously. This is quick and dirty :
new Class_Name().someMethod();
In I/O streams and AWT, we use many objects only once in the program; for them, better go for anonymous objects as follows.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
After the Edit:
new Tree();
Your intention here was to execute the code in the constructor .But your code won't compile I believe you need to put the last line inside some method.
new Class_Name();
This statement will create the object of Class_Name and constructor will be called but you are not holding the refernece of that class, so you can not call any other method. Here this Object scope will be limited where it has written, say in method or block.
A general use of it. new Thread(new RunnableTest()).start();
class RunnableTest implements Runnable{
public void run(){
for(int i=0;i<10;i++){
System.out.println("i : "+i);
}
}
}
new class_name() will create object of class_name.As you are not storing reference of it ,you will not be able to use same object in the code after this statement.But it's good practice to store the reference of object if you want to use it later in code.Which will help you to reduce efforts in managing multiple objects and memory too.
when you want to use oop you must create lots of class with a lots of attribute
and sometimes you need to use a attribute of some class in a specific class so you need to
create a object of those class by using
new Class_Name();
I have a bit of a problem. I'm making a Finite Automata checker.
Given an input, and the DFA, does it end on a accepting state.
My problem is creating a new DFA_State from another's target.
DFA_State state0, state1, curr_state, init_state, temp; //fine, I think
state0 = new DFA_State();
state1 = new DFA_State();
state0 = new DFA_State("State 0",true, state0, state1); //fine, I think
init_state = new DFA_State(state0); //fine, I think
but, this bit is throwing up problems.
temp = new DFA_State(curr_state.nextState(arr1[i]));
*
*
curr_state = new DFA_State(temp);
Thanks for any help,
Dave
Edit:
God I was retarded when I did this, AFAIK, I just wasn't thinking straight, added methods to set the values to the DFA_State object.
//in DFA_State class
public void set(DFA_State on_0, DFA_State on_1, Boolean is_accepting, String name){
this.on_0 = on_0;
this.on_1 = on_1;
this.is_accepting = is_accepting;
this.name = name;
}
//in main
DFA_State state0, state1, curr_state;
state0 = new DFA_State();
state1 = new DFA_State();
state0.set(state0, state1, false, "State 0");
state1.set(state1, state0, true, "State 1");
curr_state = state0;//initial state
//iterate across string input changing curr_state depending on char c
curr_state = getNextState(c);
//at end
if(curr_state.isAccepting())
System.out.println("Valid, " + curr_state.getName() + " is accepting);
else
System.out.println("Invalid, " + curr_state.getName() + " is not accepting);
In that first line, you declare the variables state0, state1, curr_state, init_state and temp as being variables of type DFA_State. However, that only declares them, they are not yet initialized. The next few lines are all okay. Second line creates a state without anything in it and assigns it to state0, so does the third line for state1. Fourth line overwrites your previous state0 assignment with a new DFA_State that has actual contents. Fifth line creates a DFA_State as a copy of state0 and assigns it to init_state.
Assuming there's nothing in between this and the first line of your second code block, now you'll get a problem. You're assigning temp with a new DFA_State that uses a copy-constructor with an argument relying on curr_state. But at that point, that variable hasn't been initialized yet. Just because it was declared doesn't mean it has somehow already been structured in memory. When you call nextState on it, there's simply no variable to resolve this to. Don't expect to get something like a pointer that will eventually point to a part of what you put in curr_state.
I'm just guessing, but from your code style I'd say you have a background in C or C++. Look into the differences between those languages and Java. If possible, I'd also advise you to make your DFA_State class immutable, since this is more reliable and will avoid mistakes. That means getting rid of the no-args constructor. Here's a reworking of it (not actually compiled, might contain errors):
package foundations.of.computing;
/**
*
* #author Kayotic
*/
class DFA_State {
private final String state;
private final DFA_State on_0;
private final DFA_State on_1;
private final boolean isAccepting;
//private DFA_State dummy;
public DFA_State(DFA_State arg) {
//this(arg.is_accepting(), arg.on0(), arg.on1());
state = arg.get_name();
isAccepting = arg.is_accepting();
on_0 = arg.on0();
on_1 = arg.on1();
}
public DFA_State(String name, Boolean accepting, DFA_State on0, DFA_State on1) {
state = name;
isAccepting = accepting;
on_0 = on0;
on_1 = on1;
}
public String get_name(){
return state;
}
public Boolean is_accepting() {
return isAccepting;
}
public DFA_State on0() {
return on_0;
}
public DFA_State on1() {
return on_1;
}
public DFA_State nextState(char i) {
if (i == '0') {
return on0();
} else if (i == '1') {
return on1();
} else {
System.out.println("Error with input");
return null;
}
}
}
Even if you can't make the instance variables final, it's best to at least make them private, since you already have methods for getting them.
There are better memory representations of DFAs than the object-oriented.
You should use a simple lookuptable:
int[] table = new int[vocabularyCount][stateCount];
Every State and every word gets a number, starting with 0.
Fill the table with the state transitions, or -1, if there is no transition. Now you just need the translation methods for the states and the words.
Heres a generic DFA algorithm:
public boolean checkSentence(String s, int[] finishes) {
// fill table
int state = 0; // assuming S0 is the start state
for (int i = 0; i < s.length(); i++) {
state = table[translate(s.charAt(i))][s];
}
for (int i = 0; i < finishes.length; i++) {
if (finishes[i] == state) {
return true;
}
}
return false;
}
The program is quite poorly written. Look at this in your FoundationsOfComputing.java:
state0 = new DFA_State();
state1 = new DFA_State();
state0 = new DFA_State("State 0",true, state0, state1);
You essentially created 3 instances of state - two instances which are not initialized (first two lines in your code) - all their instance variables are null.
Then you create the third instance, which you point to the first two uninitialized ones, and assign it to state0 variable. Please note, at this point, it is only the value of the variable that changes, not the values you passed in the DFA-State constructor!!! So, what you now have in state0 is a state that points to two uninitialized states.
Now let's look at the code further down in the FoundationsOfComputing.java:
while (i < arr1.length) {//loops through array
System.out.println(i + ". scan shows " + arr1[i]);
temp = new DFA_State(curr_state.nextState(arr1[i]));
System.out.println(" "+curr_state.get_name()+ " moves onto " + temp.get_name());
curr_state = new DFA_State(temp);
i++;
}
I am guessing this throws NullPointerException - that code moves to the on_0 state of state0 - which is a state that has not been initialized (all it's instance variables are null), so in the following pass of the loop, when it calls curr_state.nextState(whatever), it would return null and you are trying to pass that to the copy-constructor which would result in NPE.
Ok so we know this is homework. Let's do this instead of telling you the answer let's try and work through it on your own. If you are seeing a NullPointerException (NPE). Grab the second line of the exception:
java.lang.NullPointerException: null
at com.blah.blah.SomeObject.someMethod(SomeArgumentType):1234 <<< here
....
That 1234 is the line number in the file that contains SomeObject. If you goto that line number you can see exactly where the NPE is being generated from. For example if line 1234 was:
this.foo = bar.indexOf("caramel");
You can easily deduce what was null. No clue? Well this can never be null so this.foo isn't the problem. If this could be null you couldn't be inside that method because this points to the instance you are currently within. Therefore, the only other statement where a variable is being dereferenced is bar so bar must be null. Let's look at your code:
temp = new DFA_State(curr_state.nextState(arr1[i]));
Say you find out the line above is tossing an exception. Well there could be several things that could be null. curr_state could be null, or arr1 could be null in which case this line would blow up. However, if arr1[i] is null or curr_state.nextState() is returning null then you won't see the NPE pointing at this line, but would be coming out of the constructor should someone try to call methods on that method parameter.
Hopefully, this will give you the tools you need to track down problems in your application by understanding exception stack traces.