Getting the next Value in a ArrayList(Not working) - java

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.

Related

Robocode HashTable/method modifying values in it issues

Currently in RObocode I have a hashtable that has names as the keys and point2D objects as the values. One of the properties of these objects is the double lastSeen which is the time since the robot has been seen. Everytime I scan a robot, I would set this value to 0, this value also helps my radar become the oldest scanned radar.
public void onScannedRobot(ScannedRobotEvent e) {
String name;
EnemyInfo enemy = (EnemyInfo) enemies.get(name = e.getName());
// if the enemy is not already on the hashtable, puts it on
if (enemy == null) {
enemies.put(name, enemy = new EnemyInfo());
}
enemy.bearing = e.getBearing();
enemy.velocity = e.getVelocity();
enemy.heading = e.getHeading();
enemy.energy = e.getEnergy();
enemy.lastSeen = 0;
above is the code that upon scanning a robot, shoves it into the hashtable as an object and sets the object's lastseen property to 0;
I have made a method that increases the value (by 1) of every object's lastSeen variable by returning an enumeration of all object's lastSeen variables and adding one to each of them.
Method is below:
public static void advanceTime(EnemyInfo e) {
if (!enemies.isEmpty()) {
int i = 0;
Enumeration enum3 = enemies.elements();
do {
(e = (EnemyInfo) enum3.nextElement()).lastSeen = (e = (EnemyInfo) enum3
.nextElement()).lastSeen + 1;
i++;
System.out.println("Added one to.." + i);
} while (enum3.hasMoreElements());
}
}
However, I cannot call this method if there is nothing in the hashtable, which is why I put an if to stop the method from executing if there is nothing in the hashtable. Don't know the reason for this..
Any other method for doing this efficiently and effectively??
Storing Calculated Values
In a lot of cases, it is better to store the information to calculate a value rather than a calculated value itself. For instance, instead of storing a person's age (eg 20 years old), one would store the person's birthday (eg 5-5-95). If you store someone's age, you have to update it every year. If you store the birthday, you can simply calculate the age whenever you want.
Robocode
Back to the problem at hand. Instead of storing how old a piece of information is (age), store when the information was created (birthday). ScannedRobotEvent has a getTime() method that you can use to get the "birthday" of the scan event. Store this number. Then if you need to know how old the stored ScannedRobotEvent is, subtract this stored time from current time. This will bypass the need for an advanceTime method. To implement this update enemy.lastSeen to this:
public void onScannedRobot(ScannedRobotEvent e) {
String name;
EnemyInfo enemy = (EnemyInfo) enemies.get(name = e.getName());
// if the enemy is not already on the hashtable, puts it on
if (enemy == null) {
enemies.put(name, enemy = new EnemyInfo());
}
enemy.bearing = e.getBearing();
enemy.velocity = e.getVelocity();
enemy.heading = e.getHeading();
enemy.energy = e.getEnergy();
enemy.lastSeen = e.getTime();
Exception
There are some cases where you want to store a calculated value. GPA is a good example. GPA is a calculated value, but to calculate it you need to access every course someone has taken. In this case, if could be faster to store GPA and remember to update it whenever someone completes a new course.

Mutator methods with an Array of Objects in Java

So i have an array of Room objects, the reason its static is because I'm doing it in main.
private static Room[] rooms = new Room[6];
So in my room class, i have a method called setStatus which sets a string to the room object
public String setStatus(String answer) {
if (answer.equalsIgnoreCase("Available") || answer.equalsIgnoreCase("Occupied")
|| answer.equalsIgnoreCase("Needs cleaning (unavailable)")
|| answer.equalsIgnoreCase("For walk-ins")
|| answer.equalsIgnoreCase("For emergencies")) {
this.status = answer;
return status;
} else {
System.out.println("Status must be set to Available, Occupied or Needs cleaning (unavailable)");
return null;
}
}//end of setStatus
Now i want to set the status for each position in the array
rooms[random.nextInt(6)].setStatus("For walk-ins");
However i get a nullpointer exception when i set the status of the array, any ideas?.
the reason [rooms] static is because I'm doing it in main.
This is not your only choice - you could have declared it as a local variable inside the main method.
However i get a null pointer exception
This is because you have initialized the array object, but you have forgotten to initialize its individual elements. You need to add a loop, and create each room individually.
If you keep rooms static, add a static initialization block, like this:
static {
for (int i = 0 ; i != rooms.length ; i++) {
rooms[i] = new Room(); // You may need to pass other parameters to the constructor
}
}
If you prefer to change rooms to a local variable, you can put the for loop in your main, immediately after the declaration / initialization of the rooms array object.

Having trouble with the arraylist get method

Basically, I have an ArrayList of BudgetItem objects (BudgetItem being a class I made). Each BudgetItem has three instance variables, price, name, and quantity with setters and getters for each. I am adding each BudgetItem to the ArrayList one at a time, each with different information in the price variable. When I go to print out any price element of the ArrayList, using the get method, the console will always print the last price that was entered. Below, I will paste some sample code to help:
public class Register {
private ArrayList<BudgetItem> register = new ArrayList<BudgetItem>();
public Register(double[] price) {
//Creates a register ArrayList with specified number of
//elements and populates it with BudgetItems that contain
//the data in the price array entered in the declaration.
BudgetItem bi = new BudgetItem();
for(int i = 0; i<price.length; i++) {
bi.setPrice(price[i]);
register.add(bi);
if(i=0) { //This if statement is for debugging.
System.out.println(register.get(i).getPrice());
}
}
//This is also for debugging.
double i = register.get(0).getPrice();
System.out.println(i);
}
}
Through my debugging efforts I found that the problem is with the get method in ArrayList. No matter what I do it returns the last instance of price that was entered. My question is why won't the get method return the specified element?
Well the problem is that you always modify the same BudgetItem object.
Try :
for(int i = 0; i<price.length; i++) {
BudgetItem bi = new BudgetItem(); <-- move it inside the for loop
bi.setPrice(price[i]);
register.add(bi);
}
You are only adding a single BudgetItem and setting and resetting its price. You need to add new BudgetItems and set their prices accordingly.
Add BudgetItem bi = new BudgetItem(); inside for loop

Editable 2D Array

I want to create a 2D Array that creates a mini seating chart of an airplane. So far, I've gotten it to successfully print out something that looks like this:
1A(0) || 1B(0) || 1C(0)
2A(0) || 2B(0) || 2C(0)
3A(0) || 3B(0) || 3C(0)
4A(0) || 4B(0) || 4C(0)
The zeroes represent an empty seat, and the number one is used to represent an occupied seat.
I first created the program with arrays that were class variables for a First Class, but I wanted to make this program usable for an Economy Class section. The only difference between the two sections is the size of the array so I edited my code to look like this:
public class Seating
{
private int FIRSTCLASS= 12;
private int ECONOMYCLASS= 240;
private int occupied, column;
private String[][] seatchart;
private int[][] seatlist;
private String[][] namelist;
private String name;
public String customer;
public Seating(String seatclass)
{
seatclass.toUpperCase();
if (seatclass.equals("FIRSTCLASS"))
{
seatchart= new String[FIRSTCLASS/3][3];
seatlist= new int[FIRSTCLASS/3][3];
namelist= new String[FIRSTCLASS/3][3];
}
else
if (seatclass.equals("ECONOMY"))
{
seatchart= new String[ECONOMYCLASS/3][3];
seatlist= new int[ECONOMYCLASS/3][3];
namelist= new String[ECONOMYCLASS/3][3];
}
}
public void Creation()
{
for (int i=0; i< seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
seatlist[i][j]= 0 ;
}
}
I get an null pointer exception error around for (int i=0; i< seatlist.length; i++)
How can I fix this error?
Thanks in advance!
The problem is with this line:
seatclass.toUpperCase();
Replace it with:
seatclass = seatclass.toUpperCase();
I think you are creating the class with a string like "firstclass" rather than "FIRSTCLASS" right? Those aren't the same strings and just invoking the toUpperCase method on the string without assigning the result to a variable to then be tested means nothing happens.
Then since none of your if conditions are met, the arrays are not initialized and a null pointer exception is thrown when Completion() is called.
I'm not sure if you are new to java programming, but I wanted to add a few recommendations to your class:
public class Seating {
private static int FIRSTCLASS= 12; // Make these constants static since they pertain to all
private static int ECONOMYCLASS= 240; // instances of your class. That way there is exactly on
// copy of the variables, which is more memory efficient.
private int occupied;
private column; // Okay but Java convention is to declare each member variable on its own line
// increases code readability.
private String[][] seatchart;
private int[][] seatlist;
private String[][] namelist;
private String locSeatClass;
private String name;
public String customer; // Okay but better to leave this private and then provide getter and
// setter methods to provide access to this string. Much easier to track
// down who is changing its value in your code.
public Seating(String seatclass) { // Java convention is to place the opening bracket here not
// on the next line.
// Make sure that seatClass is not null or empty. NOTE: This is a neat trick for
// simultaneously checking for both null and empty strings in one shot. Otherwise, you have
// you have to check for null and then examine the string's length which is more code.
if ("".equalsIgnoreCase(seatClass) {
throw new IllegalArgumentException("Seat class undefined.");
}
// Store the seat class in a member variable for use. Could also be a local variable.
// My original solution is problematic because it changes the original value of the seat
// class that was passed into the constructor (you might want that information).
locSeatClass = seatclass.toUpperCase();
if (locSeatClass.equals("FIRSTCLASS"))
{
seatchart= new String[FIRSTCLASS/3][3];
seatlist= new int[FIRSTCLASS/3][3];
namelist= new String[FIRSTCLASS/3][3];
}
else if (locSeatclass.equals("ECONOMY")) {
seatchart= new String[ECONOMYCLASS/3][3];
seatlist= new int[ECONOMYCLASS/3][3];
namelist= new String[ECONOMYCLASS/3][3];
}
else {
// Throw an exception if someone passes in an unknown seat class string.
throw new IllegalArgumentException("Unknown seat class detected.")
}
}
public void creation() { // NOTE: Java convention is to begin method names with a lower
// case letter.
// This method is unnecessary. Arrays of integers are initialized with an initial value
// of zero by default. However, if you want to make your class reusable, you could change
// change the name of the this method to clear, which would allow you to clear the arrays of
// an existing object.
for (int i=0; i< seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
seatlist[i][j]= 0 ;
}
}
}
The only way that line of code can generate a NPE is if seatlist is null. Unless you assign null to seatlist somewhere else in your class, the only way it can be null is if the argument that you pass to the Seating constructor does not match either "FIRSTCLASS" or "ECONOMY". Check your call to the constructor. Also, you might want to just use seatclass.equalsIgnoreCase().
You should modify your constructor to at least warn about that eventuality, since it is vital to the proper operation of the class that any instances of Seating have valid seatlist and namelist arrays.

Java: Copy Constructor not going as planned

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.

Categories