Java - NullPointerException in a method - java

I'm writing a program that could manage universitary students with courses and subjects. The problem of the class I'm showing you is that when the method
public CorsoStudi(String unNomeCorso, ArrayList unElencoMaterie, int unIdCorso)
is called it throws a NullPointerException at line elencoEsamiDati.add(q);. So, probably the problem is with this line and the line after this:
EsameDato q = new EsameDato(unElencoMaterie.get(contatore), 0);
Eclipse doesn't advice error on writing code.
Creatore.java
import java.util.ArrayList;
import java.util.Scanner;
public class Creatore {
int counterStudenti = 0;
int counterMaterie = 0;
int counterCorsi = 0;
//int counterEsami = 0;
ArrayList<Studente> listaStudenti = new ArrayList<Studente>();
ArrayList<Materia> listaMaterie = new ArrayList<Materia>();
ArrayList<CorsoStudi> listaCorsi = new ArrayList<CorsoStudi>();
//ArrayList<EsameDato> listaEsami = new ArrayList<EsameDato>();
public void iscriviStudente(String nomeStudente, String cognomeStudente, CorsoStudi corsoStudente){
listaStudenti.add(new Studente(nomeStudente, cognomeStudente, counterStudenti, corsoStudente));
counterStudenti++;
}
public void reimmatricolaStudente(int unaMatricola, int unIdCorso){
int c = 0;
CorsoStudi unCorso = null;
for(c = 0; c < listaCorsi.size(); c++){
if(listaCorsi.get(c).getIdCorso() == unIdCorso)
unCorso = listaCorsi.get(c);
}
int contatore = 0;
for(contatore = 0; contatore < listaStudenti.size(); contatore++)
if(listaStudenti.get(contatore).getMatricola() == unaMatricola){
iscriviStudente(listaStudenti.get(contatore).getNome(), listaStudenti.get(contatore).getCognome(), unCorso);
rimuoviStudente(unaMatricola);
};
}
public void rimuoviStudente(int matricola){
int contatore;
for(contatore = 0; contatore < listaStudenti.size(); contatore++){
if(listaStudenti.get(contatore).getMatricola() == matricola)
listaStudenti.remove(contatore);
}
}
public Materia creaMateria(String nomeMateria, int crediti){
listaMaterie.add(new Materia( nomeMateria, crediti, counterMaterie));
counterMaterie++;
return listaMaterie.get(counterMaterie - 1);
}
public void creaCorsoStudi(String nomeCorso, ArrayList<Materia> materieCorso){
CorsoStudi q = new CorsoStudi( nomeCorso, materieCorso, counterCorsi);
listaCorsi.add(q);
counterCorsi++;
}
public ArrayList<Studente> cercaStudente(int opzione, String pattern){
int contatore = 0;
ArrayList<Studente> listaRicercati = new ArrayList<Studente>();
//opzione 1 = ricerca per nome
if(opzione == 1)
for(contatore = 0; contatore < listaStudenti.size(); contatore++){
if(listaStudenti.get(contatore).getNome().equalsIgnoreCase(pattern))
listaRicercati.add(listaStudenti.get(contatore));
};
//opzione 2 = ricerca per cognome
if(opzione == 2)
for(contatore = 0; contatore < listaStudenti.size(); contatore++){
if(listaStudenti.get(contatore).getCognome().equalsIgnoreCase(pattern))
listaRicercati.add(listaStudenti.get(contatore));
};
//opzione 3 = ricerca per matricola
if(opzione == 3)
for(contatore = 0; contatore < listaStudenti.size(); contatore++){
if(listaStudenti.get(contatore).getMatricola() == Integer.parseInt(pattern))
listaRicercati.add(listaStudenti.get(contatore));
};
//opzione 4 = ricerca per corsoStudi
if(opzione == 4)
for(contatore = 0; contatore < listaStudenti.size(); contatore++){
if(listaStudenti.get(contatore).getCorsoStudi().getIdCorso() == Integer.parseInt(pattern))
listaRicercati.add(listaStudenti.get(contatore));
};
return listaRicercati;
}
public Materia materiaDaId(int id){
int c = 0;
Materia materiaDaRitornare = null;
for(c = 0; c < listaMaterie.size(); c++){
if(listaMaterie.get(c).getIdMateria() == id)
materiaDaRitornare = listaMaterie.get(c);
}
return materiaDaRitornare;
}
}
CorsoStudi.java
import java.util.ArrayList;
import java.util.Scanner;
public class CorsoStudi {
private String nomeCorso;
private int idCorso;
private ArrayList<Materia> elencoMaterie;
private ArrayList<EsameDato> elencoEsamiDati;
public CorsoStudi(String unNomeCorso, ArrayList<Materia> unElencoMaterie, int unIdCorso){
nomeCorso = unNomeCorso;
elencoMaterie = unElencoMaterie;
idCorso = unIdCorso;
int contatore = 0;
//EsameDato q = null;
for(contatore = 0; contatore < unElencoMaterie.size(); contatore++){
EsameDato q = new EsameDato(unElencoMaterie.get(contatore), 0);
elencoEsamiDati.add(q);
};
}
public String getNomeCorso(){
return nomeCorso;
}
public int getIdCorso(){
return idCorso;
}
public ArrayList<Materia> getElencoMaterie(){
return elencoMaterie;
}
public ArrayList<EsameDato> getElencoEsamiDati(){
return elencoEsamiDati;
}
public String toString(){
String s = "";
s = s + "Ecco le materie di questo Corso di Studi:\n";
int c = 0;
for(c= 0; c < elencoMaterie.size(); c++){
s = s + elencoMaterie.get(c).getIdMateria() + " ";
s = s + elencoMaterie.get(c).getNomeMateria() + " (";
s = s + elencoMaterie.get(c).getCrediti() + " crediti)\n";
}
return s;
}
}

You have not initialized the field elencoEsamiDati therefore the actual value is null.
Before adding elements to an ArrayList you need to create it:
private ArrayList<EsameDato> elencoEsamiDati = new ArrayList<EsameDato>();
You may also need to initialize other fields as well.
BTW it is not a good idea to use your own language when programming, use English instead.

Related

Android - An algorithm to check recursively if a map is solvable

I am making an android Hashikawekero puzzle game, I have implemented a algorithm to spawn nodes (Islands) at random positions using a 2-d array this works fine it creates the node at random position but most of the times the map cant be solved. The map nodes spawn at random.
BoardCreation.java Class - this generates the map.
package Island_and_Bridges.Hashi;
import android.annotation.TargetApi;
import android.os.Build;
import android.util.Log;
import java.util.Random;
import static junit.framework.Assert.*;
//This class Creates the map by random using a 2d array
public class BoardCreation {
// This class member is used for random initialization purposes.
static private final Random random = new Random();
// The difficulty levels.
private static final int EASY = 0;
static public final int MEDIUM = 1;
static public final int HARD = 2;
static public final int EMPTY = 0;
private static int ConnectionFingerprint(BoardElement start, BoardElement end) {
int x = start.row * 100 + start.col;
int y = end.row * 100 + end.col;
// Swap to get always the same fingerprint independent whether we are called
// start-end or end-start
if (x > y ) {
int temp = x;
x = y;
y = temp;
}
Log.d("", String.format("%d %d" , x ,y));
return x ^ y;
}
public class State {
// The elements of the board are stored in this array.
// A value defined by "EMPTY" means that its not set yet.
public BoardElement [][] board_elements = null;
public int [][] cell_occupied = null;
// The width of the board. We only assume squared boards.
public int board_width=0;
public State(int width) {
board_width = width;
board_elements = new BoardElement[width][width];
cell_occupied = new int[width][width];
}
public State CloneWithoutConnections() {
State newstate = new State(board_width);
if (board_elements != null) {
newstate.board_elements = new BoardElement[board_elements.length][board_elements.length];
for (int i = 0; i < board_elements.length; ++i) {
for (int j = 0; j < board_elements.length; ++j) {
if (board_elements[i][j] == null)
continue;
newstate.board_elements[i][j] = board_elements[i][j].clone();
}
}
}
if (cell_occupied != null) {
assert board_elements != null;
newstate.cell_occupied = new int[board_elements.length][board_elements.length];
for (int i = 0; i < board_elements.length; ++i) {
System.arraycopy(cell_occupied[i], 0, newstate.cell_occupied[i], 0, board_elements.length);
}
}
return newstate;
}
public void AddToBridgeCache(BoardElement first, BoardElement second) {
if (first == null || second == null) { return; }
final int fingerprint = ConnectionFingerprint(first, second);
Log.d(getClass().getName(),
String.format("Fingerprint of this bridge %d", fingerprint));
// mark the end points as occupied.
cell_occupied[first.row][first.col] = fingerprint;
cell_occupied[second.row][second.col] = fingerprint;
int dcol = second.col - first.col;
int drow = second.row - first.row;
if (first.row == second.row) {
for (int i = (int) (first.col + Math.signum(dcol)); i != second.col; i += Math.signum(dcol)) {
cell_occupied[first.row][i] = fingerprint;
String.format("deleting bridge");
}
} else {
assert first.col == second.col;
for (int i = (int) (first.row + Math.signum(drow)); i != second.row; i+= Math.signum(drow)) {
cell_occupied[i][first.col] = fingerprint;
}
}
}
} // end of state
private State current_state, old_state;
static private final int WIDTH_EASY = 7;
private void NewGame(int hardness) {
switch(hardness) {
case EASY:
Log.d(getClass().getName(), "Initializing new easy game");
InitializeEasy();
old_state = getCurrentState().CloneWithoutConnections();
break;
}
}
public void ResetGame() {
if (old_state != null) {
Log.d(getClass().getName(), "Setting board_elements to old_elements");
setCurrentState(old_state.CloneWithoutConnections());
} else {
Log.d(getClass().getName(), "old_lements are zero");
}
}
public BoardCreation(int hardness) {
NewGame(hardness);
}
public boolean TryAddNewBridge(BoardElement start, BoardElement end, int count) {
assertEquals(count, 1);
assert (start != null);
assert (end != null);
final int fingerprint = ConnectionFingerprint(start, end);
Log.d(getClass().getName(),
String.format("considering (%d,%d) and (%d,%d)", start.row,start.col, end.row,end.col));
if (start.row == end.row && start.col == end.col) {
Log.d(getClass().getName(), "Same nodes selected!");
return false;
}
assert count > 0;
int dcol = end.col - start.col;
int drow = end.row - start.row;
// It must be a vertical or horizontal bridge:
if (Math.abs(dcol) > 0 && Math.abs(drow) > 0) {
Log.d(getClass().getName(), "not a horizontal or vertical bridge.");
return false;
}
// First we check whether start and end elements can take the specified bridge counts.
int count_start = start.GetCurrentCount();
int count_end = end.GetCurrentCount();
if (count_start + count > start.max_connecting_bridges ||
count_end + count > end.max_connecting_bridges) {
Log.d(getClass().getName(), "This Bridge is not allowed");
return false;
}
Log.d(getClass().getName(),
String.format("Sums:%d # (%d,%d) and %d # (%d,%d)",
count_start, start.row, start.col,
count_end, end.row, end.col));
Connection start_connection = null;
Connection end_connection = null;
// Next we check whether we are crossing any lines.
if (start.row == end.row) {
for (int i = (int) (start.col + Math.signum(dcol)); i != end.col; i += Math.signum(dcol)) {
if (getCurrentState().cell_occupied[start.row][i] > 0 &&
getCurrentState().cell_occupied[start.row][i] != fingerprint) {
Log.d(getClass().getName(), "Crossing an occupied cell.");
return false;
}
}
assert start.col != end.col;
if (start.col > end.col) {
start.connecting_east = GetOrCreateConnection(end, start.connecting_east);
end.connecting_west = GetOrCreateConnection(start, end.connecting_west);
start_connection = start.connecting_east;
end_connection = end.connecting_west;
} else {
start.connecting_west = GetOrCreateConnection(end, start.connecting_west);
end.connecting_east = GetOrCreateConnection(start, end.connecting_east);
start_connection = start.connecting_west;
end_connection = end.connecting_east;
}
} else {
assert start.col == end.col;
for (int i = (int) (start.row + Math.signum(drow)); i != end.row ; i += Math.signum(drow)) {
if (getCurrentState().cell_occupied[i][start.col] > 0 &&
getCurrentState().cell_occupied[i][start.col] != fingerprint) {
Log.d(getClass().getName(), "Crossing an occupied cell.");
return false;
}
}
if (start.row > end.row ) {
start.connecting_north = GetOrCreateConnection(end, start.connecting_north);
end.connecting_south = GetOrCreateConnection(start, end.connecting_south);
start_connection = start.connecting_north;
end_connection = end.connecting_south;
} else {
start.connecting_south= GetOrCreateConnection(end, start.connecting_south);
end.connecting_north = GetOrCreateConnection(start, end.connecting_north);
start_connection = start.connecting_south;
end_connection = end.connecting_north;
}
}
start_connection.destination = end;
end_connection.destination = start;
start_connection.second += count;
end_connection.second += count;
getCurrentState().AddToBridgeCache(start, end);
Log.d(getClass().getName(),
String.format("New bridge added. Sums:%d # (%d,%d) and %d # (%d,%d)",
count_start, start.row,start.col,
count_end, end.row,end.col));
return true;
}
private Connection GetOrCreateConnection(
BoardElement end,
Connection connection) {
if (connection!= null) { return connection; }
return new Connection();
}
#TargetApi(Build.VERSION_CODES.N)
private void InitializeEasy() {
Random rand = new Random();
String[][] debug_board_state = new String[7][7];
setCurrentState(new State(WIDTH_EASY));
for (int row = 0; row < debug_board_state.length; row++) {
for (int column = 0; column < debug_board_state[row].length; column++) {
debug_board_state[row][column] = String.valueOf(rand.nextInt(5));
}
}
for (int row = 0; row < debug_board_state.length; row++) {
for (int column = 0; column < debug_board_state[row].length; column++) {
System.out.print(debug_board_state[row][column] + " ");
}
System.out.println();
}
for (int row = 0; row < WIDTH_EASY; ++row) {
for (int column = 0; column < WIDTH_EASY; ++column) {
getCurrentState().board_elements[row][column] = new BoardElement();
getCurrentState().board_elements[row][column].max_connecting_bridges = Integer.parseInt(debug_board_state[row][column]);
getCurrentState().board_elements[row][column].row = row;
getCurrentState().board_elements[row][column].col = column;
if (getCurrentState().board_elements[row][column].max_connecting_bridges > 0) {
getCurrentState().board_elements[row][column].is_island = true;
}
}
}
}
private void setCurrentState(State new_state) {
this.current_state = new_state;
}
public State getCurrentState() {
return current_state;
}
}
What algorithm could I use to make sure the Map can be Solved (Islands Connected with Bridges) before spawning the nodes.
This is what the map looks like (don't mind the design)
One thing to consider would be to start with a blank board. Place an island. Then place another island that can be connected to the first one (i.e. on one of the four cardinal directions). Connect the two with a bridge, and increment each island's count.
Now, pick one of the two islands and place another island that it can connect. Add the bridge and increment.
Continue in this way until you've placed the number of islands that you want to place.
The beauty here is that you start with an empty board, and during construction the board is always valid.
You'll have to ensure that you're not crossing bridges when you place new islands, but that's pretty easy to do, since you know where the existing bridges are.

null pointer exception, not going inside loop

The requirement is:If <bby:SaleTenderType> value is eCommerce , it reads the SalesOrderNum and calls the required function(appends other nodes to the root node). <bby:SaleTenderType> is not eCommerce, it should call other function.
The java code is as below:
//Added for giftCard
//error
Lineitems = retailChildren.item(j).getChildNodes();
for (int z1 = 0; z1 < Lineitems.getLength(); z1++) {
if (Lineitems.item(z1).getNodeName().equalsIgnoreCase("Return")) {
NodeList returnChild1 = Lineitems.item(z1).getChildNodes();
for (int z2 = 0; z2 < returnChild1.getLength(); z2++) {
if (returnChild1.item(z2).getNodeName().equalsIgnoreCase("Tender")) {
NodeList tenderChild = Lineitems.item(z2).getChildNodes(); //Null pointer exception
for (int z3 = 0; z3 < tenderChild.getLength(); z3++) {
if (tenderChild.item(z3).getNodeName().equalsIgnoreCase("bby:SaleTenderType")) {
System.out.println("Inside");
String SaleTenderType = tenderChild.item(z3).getFirstChild().getNodeValue();
if (SaleTenderType.equalsIgnoreCase("eCommerce")) {
Lineitems = retailChildren.item(j).getChildNodes();
for (int i2 = 0; i2 < Lineitems.getLength(); i2++) {
if (Lineitems.item(i2).getNodeName().equalsIgnoreCase("Return")) {
NodeList returnChild = Lineitems.item(i2).getChildNodes();
for (int k = 0; k < returnChild.getLength(); k++) {
if (returnChild.item(k).getNodeName().equalsIgnoreCase("c360:SalesOrder")) {
String POSLOGSalesOrderNo = returnChild.item(k).getFirstChild().getNodeValue();
SalesOrderNo = POSLOGSalesOrderNo.substring(2, 12);
String SalesOrderNum = POSLOGSalesOrderNo.substring(0, 2);
if (SalesOrderNum.equalsIgnoreCase("HD") || (SalesOrderNum.equalsIgnoreCase("SV")) || (SalesOrderNum.equalsIgnoreCase("CR")) || (SalesOrderNum.equalsIgnoreCase("CW"))) {
if (!prevSalesOrder.equals(SalesOrderNo)) {
IDocEl = outdoc.createElement("IDOC");
ORDERS05.appendChild(createIDocHeader_GC(POSLOGSalesOrderNo, outdoc, EMPST, IDocEl, StoreID, true, returnChild, TRANS));
prevSalesOrder = SalesOrderNo;
}
IDocEl.appendChild(createE1EDP01forReturnLineItem_GC(outdoc, returnChild, StoreID));
}
}
}
}
}
}
}
}
} else {
Lineitems = retailChildren.item(j).getChildNodes();
for (int i3 = 0; i3 < Lineitems.getLength(); i3++) {
if (Lineitems.item(i3).getNodeName().equalsIgnoreCase("Return")) {
NodeList returnChild = Lineitems.item(i3).getChildNodes();
for (int k = 0; k < returnChild.getLength(); k++) {
if (returnChild.item(k).getNodeName().equalsIgnoreCase("c360:SalesOrder")) {
String POSLOGSalesOrderNo = returnChild.item(k).getFirstChild().getNodeValue();
SalesOrderNo = POSLOGSalesOrderNo.substring(2, 12);
String SalesOrderNum = POSLOGSalesOrderNo.substring(0, 2);
if (SalesOrderNum.equalsIgnoreCase("HD") || (SalesOrderNum.equalsIgnoreCase("SV")) || (SalesOrderNum.equalsIgnoreCase("CR")) || (SalesOrderNum.equalsIgnoreCase("CW"))) {
if (!prevSalesOrder.equals(SalesOrderNo)) {
IDocEl = outdoc.createElement("IDOC");
ORDERS05.appendChild(createIDocHeader(POSLOGSalesOrderNo, outdoc, EMPST, IDocEl, StoreID, true, returnChild));
prevSalesOrder = SalesOrderNo;
}
IDocEl.appendChild(createE1EDP01forReturnLineItem(outdoc, returnChild, StoreID));
}
}
}
}
}
}
}
}
}
//end of gift card
Here I am reading root node <Return> then checking whether it contains <Tender> .. If <Tender> is present ( obviously <bby:SaleTenderType> will be present).. else if <Tender> is not present, then other function is done.
I am getting Null pointer exception in this line NodeList tenderChild = Lineitems.item(z2).getChildNodes();
Kindly provide your valuable inputs
Thanks in advance..

Why won't this PrintWriter populate this file?

I have a program which takes Giraffes from a text file, creates an ArrayList and LinkedList out of them (redundant, I know... LinkedList was a requirement of the second part of the assignment and I liked my ArrayList), sorts out who their parents are, and then is supposed to print a VBA macro out to a file.
The file (D:\\Java\\Macro.txt) is created, but it isn't populated with anything. Why isn't anything getting printed to the file? I think that there is an issue creating an array to return to the main function though.
I suspect that the problem is within the GetYearGroup method in the Herd Class, and the way that it is interfacing with the PrintWriter located on lines 51-83 of the Main class.
Here is the code:
HW4_Name.java (main)
package giraffe;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;
public class HW4_Name {
public static void main(String[] args) throws IOException {
ArrayList<Giraffe> giraffes = new ArrayList<>();
String temp[] = new String[13];
String header = "";
String fileLocation = "theHerd.txt";
File textFile = new File(fileLocation);
Scanner in = new Scanner(textFile);
if (textFile.canRead()) {
header = in.nextLine();
while (in.hasNextLine()) {
temp = in.nextLine().split("\\t", 13);
giraffes.add(new Giraffe(temp));
}
}
Herd herd = new Herd();
for(int i = 0; i < giraffes.size(); i++){
Giraffe g = giraffes.get(i);
herd.Add(g);
}
int nGiraffes = herd.Size();
for(int i = 0; i < nGiraffes; i++){
Giraffe g = herd.GetAt(i);
int nSire = g.getSireId();
if (nSire != -1){
g.setSire(herd.Find(nSire));
}
int nDam = g.getDamId();
if (nDam != -1){
g.setDam(herd.Find(nDam));
}
}
in.close();
PrintWriter pw = new PrintWriter("C:\\Java\\Macro.txt");
int nHeight = 500;
int nWidth = 900;
int nYearHeight = nHeight / 13;
int nRectangle = 0;
for(int i = 0; i < 13; i++){
int nLowYear = 50 + 5 * i;
Giraffe[] ThisGroup = herd.GetYearGroup(nLowYear, nLowYear + 5);
int nThisGroup = ThisGroup.length;
int nXSpacing = nWidth / (nThisGroup + 1);
int nYPos = 10 + nYearHeight * i;
for(int j = 0; j < nThisGroup; j++){
nRectangle++;
int nXPos = 10 + nXSpacing/2 + nXSpacing * j;
Giraffe g = ThisGroup[j];
g.setRectangle(nRectangle);
String strName = g.getName();
pw.println("Call Box(" + nXPos + ", " + nYPos + ", \"" +strName + "\")");
}
}
for(int i = 0; i < nGiraffes; i++){
Giraffe g = herd.GetAt(i);
Giraffe gSire = g.getSire();
if (gSire != null){
int nParentRectangle = gSire.getRectangle();
nRectangle = g.getRectangle();
if (nParentRectangle > 0 && nRectangle > 0){
pw.println("Call DadLine(" + nParentRectangle + ", " + nRectangle + ")");
}
}
Giraffe gDam = g.getDam();
if(gDam != null){
int nParentRectangle = gDam.getRectangle();
if (nParentRectangle > 0 && nRectangle > 0){
pw.println("Call MomLine(" + nParentRectangle + ", " + nRectangle + ")");
}
}
}
pw.close();
}
}
Giraffe.java
package giraffe;
import java.util.ArrayList;
public class Giraffe extends Object {
private String birthLocation, subSpecies, zoo, city, state, event, name,
localId, sex, eachGiraffe;
private int gId, birthYear, sireId, damId, gRectangle;
private Giraffe gSire, gDam;
public Giraffe(String array[]){
this.sex = String.format("%-1s",array[1]);
this.birthLocation = String.format("%-12s",array[5]);
this.localId = String.format("%-7s",array[6]);
this.name = String.format("%-20s",array[7]);
this.subSpecies = String.format("%-14s",array[8]);
this.zoo = String.format("%-35s",array[9]);
this.city = String.format("%-17s",array[10]);
this.state = String.format("%-13s",array[11]);
this.event = String.format("%-7s",array[12]);
this.gId = Integer.parseInt(array[0]);
this.birthYear = Integer.parseInt(array[2].substring(0,4));
if(array[3].equals("WILD") || array[3].equals("UNK")){
this.sireId = -1;
}
else{
this.sireId = Integer.parseInt(array[3]);
}
if(array[4].equals("WILD") || array[4].equals("UNK")){
this.damId = -1;
}
else{
this.damId = Integer.parseInt(array[4]);
}
}
public String getName(){
return this.name;
}
public int getId(){
return gId;
}
public int getBirthYear(){
return birthYear;
}
public int getSireId(){
return sireId;
}
public int getDamId(){
return damId;
}
public Giraffe getSire(){
return gSire;
}
public int getRectangle(){
return gRectangle;
}
public Giraffe getDam(){
return gDam;
}
public void setSire(Giraffe nSire){
this.gSire = nSire;
}
public void setDam(Giraffe nDam){
this.gDam = nDam;
}
public void setRectangle(int nRectangle){
this.gRectangle = nRectangle;
}
public String toString(){
eachGiraffe = ("" + this.gId);
return eachGiraffe;
}
}
Herd.java
package giraffe;
public class Herd extends LinkedList{
public Herd(){
}
public void Add(Giraffe g){
InsertRight(g);
}
public Giraffe Find(int idNumber){
Giraffe g = null;
Node currNode = start;
while(currNode != null && currNode.o.getId() != idNumber){
currNode = currNode.next;
}
if(currNode.o.getId() == idNumber){
g = currNode.o;
}
return g;
}
public Giraffe GetAt(int nIndex){
Giraffe g = null;
Node currNode = start;
for(int i = 0; i < nIndex; i++){
if(currNode != null){
currNode = currNode.next;
}
}
g = currNode.o;
return g;
}
public Giraffe[] GetYearGroup(int nBegin, int nEnd){
int nGiraffes = Size();
int nInGroup = 0;
for(int i = 0; i < nGiraffes; i++){
Giraffe g = GetAt(i);
int nBirthYear = g.getBirthYear();
if (nBegin <= nBirthYear && nBirthYear < nEnd){
nInGroup++;
}
}
Giraffe[] gary = new Giraffe[nInGroup];
nInGroup = 0;
for(int i = 0; i < nGiraffes; i ++){
Giraffe g = GetAt(i);
int nBirthYear = g.getBirthYear();
if(nBegin <= nBirthYear && nBirthYear < nEnd){
gary[nInGroup] = g;
nInGroup++;
}
}
return gary;
}
}
LinkedList.java
package giraffe;
public class LinkedList {
protected Node start;
private int errorReturn;
public LinkedList(){
start = null;
}
public LinkedList(int errorValue){
start = null;
errorReturn = errorValue;
System.out.println(errorReturn);
}
public boolean isEmpty(){
return (start == null);
}
public void InsertRight(Giraffe data){
Node currNode;
if (start == null){
start = new Node(data,start);
}
else{
currNode = start;
while (currNode.next != null){
currNode = currNode.next;
}
currNode.next = new Node (data, null);
}
}
public int Size(){
int length = 0;
Node currNode = start;
while(currNode != null){
length++;
currNode = currNode.next;
}
return length;
}
public void Display(){
Node currNode = start;
System.out.println("List contents: ");
while (currNode != null){
currNode = currNode.next;
}
System.out.println("--------------------------");
}
}
Node.java
package giraffe;
public class Node {
Giraffe o;
Node next;
public Node(Giraffe giraffe, Node nextNode){
o = giraffe;
next = nextNode;
}
}
Solution
Thank you to durron597 for pointing out that the birthYear function was not comparable to the GetYearGroup function.
Replacing:
for(int i = 0; i < 13; i++){
int nLowYear = 50 + 5 * i;
With:
for(int i = 0; i < 13; i++){
int nLowYear = 1950 + 5 * i;
Resolved the issue.
I see two problems, both of which could result in the things you're seeing:
You are outputting to the C:\\Java\\Macro.txt directory, but you are using a relative path to find your theHerd.txt. Try changing your theHerd.txt file to an absolute path, or use Class.getResourceAsStream() if the file is on your classpath.
Use a debugger to see if the Giraffe objects are getting created at all
Your birth year check seems really weird:
for(int i = 0; i < 13; i++){
int nLowYear = 50 + 5 * i;
Giraffe[] ThisGroup = herd.GetYearGroup(nLowYear, nLowYear + 5);
This is only going to check years in the range 50, 55, up to 115. However, in your Giraffe class, you do this:
this.birthYear = Integer.parseInt(array[2].substring(0,4));
This is only going to work (i.e. not throw an ArrayIndexOutOfBounds exception) for 4 digit date years, none of which are in the range 50-115. However, if you set your year to a value like 0073 (you must put the leading zeroes) then your program will print results like Call Box(235, 162, "GiraffeName "). You probably want to change that 50 to 1950.
Your program has other code smells; I suggest reading things like (in order of increasing time commitment):
Java Encapsulation Concept not clear
Java naming conventions
Single Responsibility Principle
Clean Code, by Robert Martin
But these two bits of code should get you started.

CardPile Index Out of bounds

I'm currently trying to convert my code to ArrayList and I can't seem to make it work. I'm running the whole program and it tells me Index out bounds. I'm sure I forgot to add the size of the array for the cards, but I don't know how to add it. Thanks for the help!
Edit: The error I get is at the bottom. Also, it tells me to go to the removeTop method. It looks fine there.
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
public class CardPile {
private ArrayList<Card> cards = new ArrayList<Card>();
private static Random r = new Random(1);
public void addToBottom(Card c) {
if (this.cards.size() == 52) {
System.out.println("The CardPile is full. You cannot add any more Card objects.");
}
this.cards.add(c);
}
public Card removeCard(Card c) {
if (this.cards.contains(c)) {
this.cards.remove(c);
}
return null;
}
public Card removeTop() {
return this.cards.remove(0);
}
public int searchValue(int value) {
int count = 0,
for (int i = 0;i < this.cards.size();i++) {
if (this.cards.get(i).getValue() == value) {
count++;
}
}
//System.out.println("Count = "+count);
return count;
}
public Card[] removeAll(int value)
//System.out.println("(removeAll) cards ="+ cards);
int count = searchValue(value);
Card[] removed = new Card[count];
int deletedCount = 0;
int i = 0;
while (deletedCount < count) {
if (this.cards.get(i).getValue() == value) {
removed[deletedCount] = this.cards.remove(i);
deletedCount++;
} else {
i++;
}
}
return removed;
}
public int getNumberCards() {
return this.cards.size();
}
public String toString() {
if (this.cards.isEmpty()) {
return "";
}
String builder = "";
for (int i = 0;i < this.cards.size() - 1;i++) {
builder = builder + this.cards.get(i) + ", ";
}
builder = builder + this.cards.get(this.cards.size() - 1);
return builder;
}
public void shuffle() {
if (this.cards.isEmpty()) {
return;
}
for (int count = 0; count < 100000;count++) {
int i = r.nextInt(this.cards.size());
int j = r.nextInt(this.cards.size());
Card temp = this.cards.get(i);
this.cards.set(i, this.cards.get(j));
this.cards.set(j, temp);
}
}
public static CardPile makeFullDeck() {
CardPile deck = new CardPile();
for (int suit = 0;suit < 4;suit++) {
for (int value = 1; value <= 13;value++) {
deck.addToBottom(new Card(suit, value));
}
}
deck.shuffle();
return deck;
}
}
**Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at CardPile.removeTop(CardPile.java:40)
at GoFish.dealCards(GoFish.java:112)
at GoFish.main(GoFish.java:13)**
EDIT:
This is the Player class:
public class Player {
private boolean[] books;
private CardPile pile;
private static int MAXIMUM_VALUE_CARD = 13;
public Player()
{
this.pile = new CardPile();
this.books = new boolean[13]; //by default all are false
}
public boolean hasCard(int value)
{
return this.pile.searchValue(value) > 0;
}
public Card[] removeAll(int value)
{
return this.pile.removeAll(value);
}
public void addAll(Card[] cards)
{
for (int i = 0; i < cards.length; i++)
{
this.pile.addToBottom(cards[i]);
}
}
//optional additional method
public void addCard(Card card)
{
this.pile.addToBottom(card);
}
public int getNumberCards()
{
return this.pile.getNumberCards();
}
public int countBooks()
{
int count = 0;
for (int i = 0; i < MAXIMUM_VALUE_CARD; i++)
{
if (books[i])
{
count++;
}
}
return count;
}
public void addBook(int value)
{
this.books[value - 1] = true;
}
public void printHand()
{
System.out.println("Player's hand is " + this.pile);
}
}
And this is the GoFish class:
import java.util.Scanner;
public class GoFish {
private static Scanner reader;
public static void main(String[] args)
{
System.out.println("How many players?");
reader = new Scanner(System.in);
int numberPlayers = reader.nextInt();
Player[] players = createPlayersArray(numberPlayers);
int currentTurn = 0;
CardPile deck = CardPile.makeFullDeck();
dealCards(deck, players);
int maximumRetries = 2;
int numRetries = 0;
while(deck.getNumberCards() > 0 && players[currentTurn].getNumberCards() > 0)
{
updateBooks(players[currentTurn]);
if (numRetries == maximumRetries)
{
numRetries = 0;
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
System.out.println("Player " + currentTurn + ", here is your hand. What card would you like to ask for?");
players[currentTurn].printHand();
int queryCard = reader.nextInt();
System.out.println("And from whom would you like to get it from?");
int queryPlayer = reader.nextInt();
if (queryCard < 1 || queryCard > 13 || queryPlayer < 0 || queryPlayer >= numberPlayers || queryPlayer == currentTurn)
{
System.out.println("Invalid entries. Please retry");
numRetries++;
}
else
{
numRetries = 0;
boolean hasCard = players[queryPlayer].hasCard(queryCard);
if (hasCard)
{
System.out.println("Cards found!");
Card[] removed = players[queryPlayer].removeAll(queryCard);
players[currentTurn].addAll(removed);
}
else
{
System.out.println("Go fish!");
Card top = deck.removeTop();
System.out.println("You drew " + top);
players[currentTurn].addCard(top);
//check to make sure this extra card didn't form a book
//Note this could happen even if it doesn't match the card they were asking about
updateBooks(players[currentTurn]);
if (top.getValue() == queryCard)
{
System.out.println("You successfully went fishing!");
}
else
{
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
}
}
}
//calculate the winner now
int maxPlayer = 0;
int maxPlayerBooks = players[0].countBooks();
for (int i = 1; i < numberPlayers; i++)
{
int currentBooks = players[i].countBooks();
if (currentBooks > maxPlayerBooks)
{
maxPlayer = i;
maxPlayerBooks = currentBooks;
}
}
System.out.println("Congratulations! Player " + maxPlayer + " you have won the game by accumulating " + maxPlayerBooks + " books!");
}
private static Player[] createPlayersArray(int numPlayers)
{
Player[] players = new Player[numPlayers];
for (int i = 0; i < numPlayers; i++)
{
players[i] = new Player();
}
return players;
}
private static void dealCards(CardPile deck, Player[] players)
{
final int NUMBER_CARDS_PER_PLAYER = 7;
for (int i = 0; i < NUMBER_CARDS_PER_PLAYER * players.length; i++)
{
Card next = deck.removeTop();
players[i % players.length].addCard(next);
}
}
private static void updateBooks(Player player)
{
for (int i = 1; i <= 13; i++)
{
//alternative option would be to modify the hasCard method to return an int instead of boolean. Then we could just count (this is probably better design)
Card[] valued = player.removeAll(i);
if (valued.length == 4)
{
player.addBook(i);
}
else
{
player.addAll(valued);
}
}
}
}

calculating with java with two file program

I have a question on how to calculate with java. In my case, I think I am doing the calculations right, but when I run it, I get a few 0s and some absurd number. How can I fix this? Any help will be greatly appreciated. Below is my code:
public class CO2Footprint {
private int NumberOfPeople, CO2PerPerson, lightBulbs, months;
private double TotalEmission, ReductionPerPaper, ReductionPerPlastic,
ReductionPerGlass, ReductionPerCan, TotalReduction,
FamilyNetEmission, annualGasoline, electricityBill
, lightBulbsRecycled, annualFuelUse, averageMonthlyCostElec,
emissionFactor, monthlyCostSeptElec, monthlyCostOct, monthlyCostNov,
averagePricePerKilowatt, totalWaste, elecPrice, NetEmission;
private boolean paper, plastic, glass, can;
CO2Footprint(int numPeople, boolean bpaper, boolean bplastic, boolean
bglass, boolean bcans, double annuallGasoline
, double electricityyPrice, int lighttBulbs){
NumberOfPeople = 0;
paper = bpaper;
plastic = bplastic;
glass = bglass;
can = bcans;
ReductionPerPaper = 184;
CO2PerPerson = 1018;
ReductionPerPlastic = 25.6;
ReductionPerGlass = 46.6;
ReductionPerCan = 165.8;
TotalEmission = 0;
annualGasoline = 16.5;
electricityBill = 0;
lightBulbs = 10;
lightBulbsRecycled = 0;
annualFuelUse = 0;
averageMonthlyCostElec = 0;
emissionFactor = 1.37;
monthlyCostSeptElec = 551.51;
monthlyCostOct = 392.84;
monthlyCostNov = 445.42;
months = 12;
averagePricePerKilowatt = 4.83;
totalWaste = 0;
NetEmission = 0.0;
}
// method for calculating total emission
public double totalEmission(){
TotalEmission = NumberOfPeople * CO2PerPerson;
return TotalEmission;
}
// method for calculating CO2 reduction
public double reduction(){
TotalReduction = 0;
ReductionPerPaper = 0;
ReductionPerPlastic = 0;
ReductionPerGlass = 0;
ReductionPerCan = 0;
if(paper = true){
ReductionPerPaper = 184;
}else{
ReductionPerPaper = 0;
}
if(plastic = true){
ReductionPerPlastic = 25.6;
}else{
ReductionPerPlastic = 0;
}
if(glass = true){
ReductionPerGlass = 46.6;
}else{
ReductionPerGlass = 0;
}
if(can = true){
ReductionPerCan = 165.8;
}else{
ReductionPerCan = 0;
}
TotalReduction = ReductionPerPaper + ReductionPerPlastic +
ReductionPerGlass + ReductionPerCan + (lightBulbs * 1.37 * 73);
return TotalReduction;
}
public double calcAnnualFuelUseGallonCO2(){
annualFuelUse = annualGasoline * 12 * 12;
return annualFuelUse;
}
public double calcElectricityBill(){
return (averageMonthlyCostElec / averagePricePerKilowatt) * emissionFactor * months;
}
public double electrictyPrice(){
return averagePricePerKilowatt;
}
public double calcWaste(){
TotalReduction = 0;
ReductionPerPaper = 0;
ReductionPerPlastic = 0;
ReductionPerGlass = 0;
ReductionPerCan = 0;
if(paper = true){
ReductionPerPaper = 184;
}else{
ReductionPerPaper = 0;
}
if(plastic = true){
ReductionPerPlastic = 25.6;
}else{
ReductionPerPlastic = 0;
}
if(glass = true){
ReductionPerGlass = 46.6;
}else{
ReductionPerGlass = 0;
}
if(can = true){
ReductionPerCan = 165.8;
}else{
ReductionPerCan = 0;
}
totalWaste = ReductionPerPaper + ReductionPerPlastic +
ReductionPerGlass + ReductionPerCan;
return totalWaste;
}
public double calcBulbsEmissionReduction(){
return lightBulbs * 1.37 * 73;
}
public double calcNetEmission(){
NetEmission = TotalEmission - CO2PerPerson;
return NetEmission;
}
}
If it helps, below is the code for how I called the methods:
import java.util.ArrayList;
public class CO2FootprintTester {
public static void main(String args[]){
ArrayList<CO2Footprint> CO2 = new ArrayList<CO2Footprint>();
CO2.add(new CO2Footprint(1, true, true, true, true, 16.5, 4.83, 10));
CO2Footprint data;
for(int i = 0; i < CO2.size(); i++){
data = CO2.get(i);
data.calcAnnualFuelUseGallonCO2();
data.calcBulbsEmissionReduction();
data.calcElectricityBill();
data.calcWaste();
data.electrictyPrice();
data.reduction();
data.totalEmission();
}
// create table
System.out.println("___________________________________________________"
+ "_____________________________________________________________________________");
System.out.printf("%65s%44s%n", " Pounds of CO2 Emitted From: |",
" Pounds of CO2 Reduced From: ");
System.out.println("___________________________________________________"
+ "_____________________________________________________________________________");
System.out.printf("%1s%25s%25s%25s%25s%n%n", "Gas", "Electricity",
"Waste", "Recycling", "New Bulbs");
// call methods
for(int i = 0; i < CO2.size(); i++){
data = CO2.get(i);
System.out.printf("%5.5f%15.5f%15.5f%15.5f%15.5f", data.calcAnnualFuelUseGallonCO2(), data.calcElectricityBill(),
data.totalEmission(), data.calcNetEmission(), data.calcBulbsEmissionReduction());//,
//data.calcElectricityBill(), data.totalEmission(), data.calcNetEmission(),
//data.calcBulbsEmissionReduction());
}
}
}
Seems like you are facing the problem of using double data type precision. double data type is sometimes troublesome in precision calculations like monetary values etc.
It is recommended to use BigDecimal to ensure precision while arithmetic operations.
More information can be found at this post

Categories