guys. Right now, I have an array of objects that I've assigned from reading in a text file, and I need a method that searches for a string that matches with the object and, if found, decreases the capacity of the array and deletes that element. The method is the deletePhone() method in the Provider class, but I can't seem to figure out what I'm doing wrong. This first class is only used to read in the file.
public static void main(String[] args) throws IOException {
String fileNameIn = args[0];
Provider provObj = new Provider();
provObj.readCellPhoneFile(fileNameIn);
System.out.println(provObj.summary());
System.out.println(provObj.rates());
System.out.println(provObj.listByNumber());
System.out.println(provObj.listByBill());
System.out.println(provObj.excludedRecordsList());
}
}
This is the main class that I'm having problems with. It's only the deletePhone() method that I can't seem to figure out.
import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
import java.io.IOException;
import java.text.DecimalFormat;
public class Provider {
private String name;
private CellPhone[] phones;
private String[] excludedRecords;
/**
* Constructor for Provider class.
*/
public Provider() {
name = "not yet assigned";
phones = new CellPhone[0];
excludedRecords = new String[0];
}
/**
* Reads in file name and assigns data.
*
* #param fileNameIn Input for file name from main
* #throws IOException from scanning file name
*/
public void readCellPhoneFile(String fileNameIn) throws IOException {
//Reads in file name and creates Scanner object
File fileIn = new File(fileNameIn);
Scanner scanFile = new Scanner(fileIn);
//Assigns name from first line
name = scanFile.nextLine();
//Assigns data from file to different categories
while (scanFile.hasNextLine()) {
Scanner scanPhone = new Scanner(scanFile.nextLine());
scanPhone.useDelimiter(", *");
String phoneType = scanPhone.next();
char phoneChar = phoneType.toUpperCase().charAt(0);
//Assigns phone to different category
switch (phoneChar) {
case 'F':
String number = scanPhone.next();
int texts = Integer.parseInt(scanPhone.next());
int minutes = Integer.parseInt(scanPhone.next());
FlipPhone flip1 = new FlipPhone(number, texts, minutes);
addPhone(flip1);
break;
case 'S':
number = scanPhone.next();
texts = Integer.parseInt(scanPhone.next());
minutes = Integer.parseInt(scanPhone.next());
int data = Integer.parseInt(scanPhone.next());
SmartPhone smart1 = new SmartPhone(number, texts, minutes, data);
addPhone(smart1);
break;
case 'I':
number = scanPhone.next();
texts = Integer.parseInt(scanPhone.next());
minutes = Integer.parseInt(scanPhone.next());
data = Integer.parseInt(scanPhone.next());
int iMessages = Integer.parseInt(scanPhone.next());
IPhone iPhone1 = new IPhone(number, texts,
minutes, data, iMessages);
addPhone(iPhone1);
break;
case 'A':
number = scanPhone.next();
texts = Integer.parseInt(scanPhone.next());
minutes = Integer.parseInt(scanPhone.next());
data = Integer.parseInt(scanPhone.next());
int hotspotMin = Integer.parseInt(scanPhone.next());
Android android1 = new Android(number, texts,
minutes, data, hotspotMin);
addPhone(android1);
break;
default:
String unrecognized = scanPhone.nextLine();
unrecognized = phoneType + unrecognized;
addExcludedRecord(unrecognized);
}
}
}
/**
* Returns string for provider name.
*
* #return String
*/
public String getName() {
return name;
}
/**
* Assigns a name input as provider name.
*
* #param nameIn Input for provider name
*/
public void setName(String nameIn) {
name = nameIn;
}
/**
* Returns CellPhone array for phones.
*
* #return CellPhone[]
*/
public CellPhone[] getPhones() {
return phones;
}
/**
* Returns string array for excluded records.
*
* #return String[]
*/
public String[] getExcludedRecords() {
return excludedRecords;
}
/**
* Adds phone to array of phones.
*
* #param newPhoneIn Input for phone object
*/
public void addPhone(CellPhone newPhoneIn) {
//Increases size of phones array
CellPhone[] newPhones = new CellPhone[phones.length + 1];
for (int i = 0; i < phones.length; i++) {
newPhones[i] = phones[i];
}
phones = newPhones;
//Adds CellPhone object to phones array
phones[phones.length - 1] = newPhoneIn;
}
/**
* Determines if phone number is found and deleted.
*
* #return boolean
* #param numberIn Input for phone number
*/
public boolean deletePhone(String numberIn) {
boolean delete = false;
int deleteIndex = -1;
//Searches for phone number match
for (int i = 0; i < phones.length; i++) {
if (numberIn.equals(phones[i].getNumber())) {
deleteIndex = i;
}
}
if (deleteIndex > -1) {
for (int i = deleteIndex; i < phones.length - 1; i++) {
phones[i] = phones[i + 1];
phones[phones.length - 1] = null;
CellPhone[] newPhones = new CellPhone[phones.length - 1];
phones = newPhones;
}
return true;
}
else {
return false;
}
}
/**
* Adds unrecognized phone to excluded records.
*
* #param excRecIn Input for unrecognized phone
*/
public void addExcludedRecord(String excRecIn) {
//Increases capacity of excludedRecords
String[] newExcRecords = new String[excludedRecords.length + 1];
for (int i = 0; i < excludedRecords.length; i++) {
newExcRecords[i] = excludedRecords[i];
}
excludedRecords = newExcRecords;
//Adds excRecIn to array
excludedRecords[excludedRecords.length - 1] = excRecIn;
}
/**
* Returns list of cell phones in phones array.
*
* #return String
*/
public String toString() {
String result = "";
for (CellPhone phone : phones) {
result += phone + "\n";
}
return result;
}
/**
* Calculates total bill for all phones.
*
* #return double
*/
public double calculateTotalBill() {
double totalBill = 0;
for (int i = 0; i < phones.length; i++) {
totalBill += phones[i].calculateBill();
}
return totalBill;
}
/**
* Calculates total number of texts for all phones.
*
* #return int
*/
public int calculateTotalTexts() {
int totalTexts = 0;
for (int i = 0; i < phones.length; i++) {
totalTexts += phones[i].getTexts();
}
return totalTexts;
}
/**
* Calculates total number of minutes for all phones.
*
* #return int
*/
public int calculateTotalMinutes() {
int totalMinutes = 0;
for (int i = 0; i < phones.length; i++) {
totalMinutes += phones[i].getMinutes();
}
return totalMinutes;
}
/**
* Calculates total data for smartphones.
*
* #return int
*/
public int calculateTotalData() {
int totalData = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof SmartPhone) {
totalData += ((SmartPhone) phones[i]).getData();
}
}
return totalData;
}
/**
* Calculates total hotspot minutes for Androids.
*
* #return int
*/
public int calculateTotalHotspotMin() {
int totalHotspotMin = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof Android) {
totalHotspotMin += ((Android) phones[i]).getHotspotMin();
}
}
return totalHotspotMin;
}
/**
* Calculates total iMessage count for iPhones.
*
* #return int
*/
public int calculateTotalIMessages() {
int totalIMessages = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof IPhone) {
totalIMessages += ((IPhone) phones[i]).getIMessages();
}
}
return totalIMessages;
}
/**
* Returns string for summary report.
*
* #return String
*/
public String summary() {
DecimalFormat dfmt = new DecimalFormat("$#,000.00");
String summary = "------------------------------"
+ "\nSummary for " + getName()
+ "\n------------------------------"
+ "\nNumber of cell phones: " + phones.length
+ "\nTexts: " + calculateTotalTexts()
+ "\nTalk Minutes: " + calculateTotalMinutes()
+ "\nData: " + calculateTotalData()
+ "\nHotspot Minutes: " + calculateTotalHotspotMin()
+ "\niMessages: " + calculateTotalIMessages()
+ "\nBill Total: " + dfmt.format(calculateTotalBill());
return summary;
}
/**
* Returns string for different rates.
*
* #return String
*/
public String rates() {
DecimalFormat dfmt = new DecimalFormat("0.00");
String rates = "\n------------------------------\n"
+ "Rates for " + getName()
+ "\n------------------------------\n"
+ "FlipPhone Talk Rate: $" + dfmt.format(FlipPhone.TALK_RATE)
+ " Text Rate: $" + dfmt.format(FlipPhone.TEXT_RATE)
+ "\nSmartPhone Talk Rate: $" + dfmt.format(SmartPhone.TALK_RATE)
+ " Text Rate: $" + dfmt.format(SmartPhone.TEXT_RATE)
+ " Max Talk Time: " + SmartPhone.MAX_TALK_TIME
+ "\n iPhone iMessage Rate: $" + dfmt.format(IPhone.IMESSAGE_RATE)
+ "\n Android Hotspot Rate: $" + dfmt.format(Android.HOTSPOT_RATE)
+ "\n";
return rates;
}
/**
* Returns string of phones sorted by number.
*
* #return String
*/
public String listByNumber() {
Arrays.sort(phones);
String listByNumber = "------------------------------"
+ "\nCell Phones by Number"
+ "\n------------------------------\n";
for (CellPhone phone : phones) {
listByNumber += "\n" + phone.toString() + "\n";
}
return listByNumber;
}
/**
* Returns string of phones sorted by bill.
*
* #return String
*/
public String listByBill() {
Arrays.sort(phones, new CellPhoneBillComparator());
String listByBill = "------------------------------"
+ "\nCell Phones by Billing Amount"
+ "\n------------------------------\n";
for (CellPhone phone : phones) {
listByBill += "\n" + phone.toString() + "\n";
}
return listByBill;
}
/**
* Returns string excluded records.
*
* #return String
*/
public String excludedRecordsList() {
String excRecList = "------------------------------"
+ "\nExcluded Records"
+ "\n------------------------------\n";
for (String unrecPhones : excludedRecords) {
excRecList += "\n" + unrecPhones + "\n";
}
return excRecList;
}
}
CellPhone[] newPhones = new CellPhone[phones.length - 1];
phones = newPhones;
This line declares a new array, but does not fill any values, they are all null. You need to loop through newPhones and assign all the values.
CellPhone[] newPhones = new CellPhone[phones.length - 1];
for (int i = 0; i < newPhones.length; i++) {
newPhones[i] = phones[i];
}
phones = newPhones;
Please move phones[phones.length - 1] = null; out of for loop. Then you need some code to copy data between phones and newPhones, move those code to outside of for loop, too.
for (int i = deleteIndex; i < phones.length - 1; i++) {
phones[i] = phones[i + 1];
// Move three lines of code
phones[phones.length - 1] = null; // <= Problem here
CellPhone[] newPhones = new CellPhone[phones.length - 1];
// Need some code to copy data
phones = newPhones;
}
Finally, anyway, you must copy data to the new array, so I think you should copy it from the beginning:
CellPhone[] newPhones = new CellPhone[phones.length - 1];
int oldIndex = 0, newIndex = 0;
while (oldIndex < phones.length) {
if (oldIndex != deleteIndex) { // Skip copying deleted number
newPhones[newIndex++] = phones[oldIndex];
}
oldIndex++;
}
The problem should happen at the loop when you tried to set your last element to null when loop and copy:
if (deleteIndex > -1) {
for (int i = deleteIndex; i < phones.length - 1; i++) {
phones[i] = phones[i + 1];
phones[phones.length - 1] = null; //<====== This line
CellPhone[] newPhones = new CellPhone[phones.length - 1];
phones = newPhones;
}
return true;
}
else {
return false;
}
At any loop time, the 1st row copys the next element to the current index, but it would be a problem that every time you set the last element to null, because that will happen before you can copy it into the previous element of the array.
I would suggest to change to:
if (deleteIndex > -1) {
for (int i = deleteIndex; i < phones.length - 1; i++) {
phones[i] = phones[i + 1];
}
CellPhone[] newPhones = new CellPhone[phones.length - 1];
System.arraycopy(phones, 0, newPhones, 0, phones.length - 1);
return true;
}
else {
return false;
}
if (deleteIndex > -1) {
CellPhone[] tmp = new CellPhone[phones.length - 1]; // smaller array
//copy everything before deleteIndex
System.arraycopy(phones, 0, tmp, 0, deleteIndex);
//copy everything after deleteIndex
if (deleteIndex < phones.length - 1)
{
System.arraycopy(phones, deleteIndex+1, tmp, deleteIndex,
phones.length - 1 - deleteIndex);
}
phones=tmp; // use new smaller array
}
Arrays are a headache, i prefer ArrayLists; try this
public boolean deletePhone(String numberIn) {
boolean phoneExists = false;
List<String> phoneList = new ArrayList<>();
for (int i = 0; i < phones.length; i++) {
if (!numberIn.equals(phones[i].getNumber())) {
phoneList.add(phones[i].getNumber());
phoneExists = true;
}
}
phones = phoneList.toArray(new String[phoneList.size()]);
return phoneExists;
}
If you don't like lists, here's a solution using just arrays:
public boolean deletePhone(String numberIn) {
boolean phoneExists = false;
String[] newPhones;
int newLength = phones.length;
for (int i = 0; i < phones.length; i++) {
if (numberIn.equals(phones[i].getPhones())) {
phones[i] = null;
newLength--;
phoneExists = true;
}
}
newPhones = new CellPhone[newLength];
for (int i = 0, j = 0; i < phones.length; i++) {
if (phones[i] != null) {
newPhones[j++] = phones[i];
}
}
phones = newPhones;
return phoneExists;
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to place ships on a console based board game, I have the following errors and not sure how to debug them.
Exception in thread "main" java.lang.NullPointerException
at NavalBattle.Board.print(Board.java:570)
at NavalBattle.Board.placeShipsP1(Board.java:267)
at NavalBattle.Board.(Board.java:61)
at NavalBattle.Controller.start(Controller.java:29)
at NavalBattle.Controller.main(Controller.java:21)
line 570 is value = this.ships2[row][col].toString();
import java.util.Scanner;
public class Controller {
/**
* The board that represents the current state of the game.
*/
private Board board;
public Controller() {}
/**
* This creates one Library object and calls its start method.
*
* #Param args
*/
public static void main(String[] args) {
new Controller().start();
}
int PL;
/**
* The PLrimary method that starts and coordinates a game. Call this to
* begin a new game.
*/
public void start() {
this.board = new Board();
Scanner scanner = new Scanner(System.in);
this.board.moveShip();
while (!this.board.isGameOver()) {
PL = 1;
this.board.moveShip();
PL = 2;
this.board.moveShip2(null);
this.board.remap();
this.board.moveShip2(null);
System.out.println("Enter a row and column number at which to shoot (e.g., 2,3): ");
String[] coordinates = scanner.nextLine().split(",");
if (coordinates.length != 2) {
System.out.println("PLlease enter coordinates in the correct format.");
continue;
}
int row = Integer.parseInt(coordinates[0].trim());
int column = Integer.parseInt(coordinates[1].trim());
this.board.bombOp(row, column);
}
if (PL == 1);{
System.out.println("Game Over Player 2 wins");
}
if (PL == 2){
System.out.println("Game Over Player 1 wins");
}
}
}
// Board Class
import java.util.ArrayList;
import java.util.Scanner;
public class Board {
int x = 0;
int y = 0;
ArrayList<Ships> player1 = new ArrayList<>();
ArrayList<Ships> player2 = new ArrayList<>();
/**
* The number of shots that have hit ships
*/
private int hitCount;
/**
* Track the locations of the board that have been fired upon
*/
private boolean[][] locationsFiredUpon;
/**
* Track the ships in the game
*/
private Ships[][] ships;
private Ships[][] ships2;
private Ships[][] shipsM;
/**
* The number of ships sunk
*/
private int shipsSunk;
/**
* The number of shots fired
*/
private int shotsFired;
/**
* Constructor. Initializes internal counters and populates the game
* board with randomly placed ships.
*/
public Board() {
this.hitCount = 0;
this.shipsSunk = 0;
this.shotsFired = 0;
board();
this.ships = new Ships[6][9];
this.ships2 = new Ships[6][9];
this.locationsFiredUpon = new boolean[6][9];
for (int row=0; row < this.ships.length; row++) {
for (int col=0; col < this.ships[row].length; col++) {
this.ships[row][col] = new Conflict();
this.locationsFiredUpon[row][col] = false;
}
}
this.placeShipsP1();
this.placeShipsP2();
this.moveShip();
this.moveShip2(player1);
}
public void remap() {
board();
this.locationsFiredUpon = new boolean[6][9];
for (int row=0; row < this.ships.length; row++) {
for (int col=0; col < this.ships[row].length; col++) {
this.ships[row][col] = new Conflict();
this.locationsFiredUpon[row][col] = false;
}
}
}
/**
* Constructor for testing. Accepts an input ship array and does not
* attempt to place ships
* #param shipArray
*/
public Board(Ships[][] shipArray) {
this.hitCount = 0;
this.shipsSunk = 0;
this.shotsFired = 0;
this.ships = shipArray;
this.locationsFiredUpon = new boolean[6][9];
for (int row=0; row < this.ships.length; row++) {
for (int col=0; col < this.ships[row].length; col++) {
this.locationsFiredUpon[row][col] = false;
}
}
}
public void board(){
this.ships = new Ships[6][9];
this.ships2 = new Ships[6][9];
}
/**
* Get the number of shots fired that have hit a ship.
* #return The number of shots fired that have hit a ship
*/
public int getHitCount() {
return this.hitCount;
}
/**
* Get the game board.
* #return A 2-D array of Ships representing the game
*/
public Ships[][] getShipArray() {
return this.ships;
}
public Ships[][] getShipArray2() {
return this.ships2;
}
/**
* Get the number of ships sunk.
* #return The number of ships sunk
*/
public int getShipsSunk() {
return this.shipsSunk;
}
/**
* Get the number of shots fired so far.
* #return The number of shots fired
*/
public int getShotsFired() {
return this.shotsFired;
}
/**
* Create an list of ships that can be placed on the board:
* - 1 battleship
* - 2 cruisers
* - 3 destroyers
* - 4 submarines
* #return ships to be placed on the board
*/
private ArrayList<Ships> generateInitialShipArrayList1() {
ArrayList<Ships> ship = new ArrayList<Ships>();
for (int i=0; i<1; i++) {
ship.add(new Battleship());
}
for (int i=0; i<0; i++) {
ship.add(new Minesweeper());
}
for (int i=0; i<0; i++) {
ship.add(new Destroyer());
}
for (int i=0; i<0; i++) {
ship.add(new Submarine());
}
for (int i=0; i<0; i++) {
ship.add(new Mines());
}
return ship;
}
private ArrayList<Ships> generateInitialShipArrayList2() {
ArrayList<Ships> ship2 = new ArrayList<Ships>();
for (int i=1; i<2; i++) {
ship2.add(new Battleship());
}
for (int i=1; i<1; i++) {
ship2.add(new Minesweeper());
}
for (int i=1; i<1; i++) {
ship2.add(new Destroyer());
}
for (int i=1; i<1; i++) {
ship2.add(new Submarine());
}
for (int i=1; i<1; i++) {
ship2.add(new Mines());
}
return ship2;
}
/**
* Indicate whether the game is over by checking if all ships have been
* sunk.
* #return true if all ships are sunk; otherwise false
*/
public boolean isGameOver() {
return (this.shipsSunk == 1);
}
/**
* Whether the specified position is occupied by a ship and is not empty
* sea.
* #param row
* #param column
* #return true if the position has a ship; else false
*/
public boolean isOccupied(int row, int column) {
System.out.println("Occupardo, you no go here");
return !(this.ships[row][column] instanceof Conflict);
}
public void placeShipsP1() {
System.out.println("");
print();
ArrayList<Ships> shipsToMove = this.generateInitialShipArrayList1();
player1 = this.generateInitialShipArrayList1();
boolean okToPlaceShipHere = false;
int row = 0;
int column = 0;
String Tp = "1";
boolean horizontal = false;
if(okToPlaceShipHere = false){
System.out.println("Occupardo, you no go here");
}
for (Ships ship : player1) {
while (!okToPlaceShipHere) {
Scanner scanner = new Scanner( System.in );
System.out.println("player1 enter a row and column (e.g., 2,3)");
System.out.println("please enter the row of " + ship.getShipType());
String[] coordinates = scanner.nextLine().split(",");
if (coordinates.length != 2) {
System.out.println("Please enter coordinates in the correct format.");
continue;
}
row = Integer.parseInt(coordinates[0].trim());
column = Integer.parseInt(coordinates[1].trim());
ship.setX(row);
ship.setY(column);
System.out.println(ship.getX() + " " + ship.getY());
// row = Random.nextInt(6);
// column = Random.nextInt(9);
horizontal = true;
okToPlaceShipHere = ship.okToPlaceShipAt(row, column, horizontal, this);
}
if( okToPlaceShipHere = true){
this.bombOp(row, column);
}
ship.setBowColumn(column);
ship.setBowRow(row);
ship.setPlayer(Tp);
ship.setX(row);
ship.setY(column);
System.out.println(ship.getX() + " " + ship.getY() + " " + ship.getPlayer());
ship.setHorizontal(horizontal);
this.placeShipIntoShipsArray(ship);
okToPlaceShipHere = false;
System.out.println("");
print();
}
}
public void placeShipsP2() {
System.out.println("");
print();
ArrayList<Ships> shipsToPlace = this.generateInitialShipArrayList1();
player2 = this.generateInitialShipArrayList2();
boolean okToPlaceShipHere = false;
int row = 0;
int column = 0;
String Tp = "2";
boolean horizontal = false;
if(okToPlaceShipHere = false){
System.out.println("Occupardo, you no go here");
}
for (Ships ship : player2) {
while (!okToPlaceShipHere) {
Scanner scanner = new Scanner( System.in );
System.out.println("Player 2 enter a row and column (e.g., 2,3)");
System.out.println("please enter the row of " + ship.getShipType());
String[] coordinates = scanner.nextLine().split(",");
if (coordinates.length != 2) {
System.out.println("Please enter coordinates in the correct format.");
continue;
}
row = Integer.parseInt(coordinates[0].trim());
column = Integer.parseInt(coordinates[1].trim());
ship.setX(row);
ship.setY(column);
System.out.println(ship.getX() + " " + ship.getY());
// row = random.nextInt(6);
// column = random.nextInt(9);
horizontal = true;
okToPlaceShipHere = ship.okToPlaceShipAt(row, column, horizontal, this);
}
ship.setBowColumn(column);
ship.setBowRow(row);
ship.setPlayer(Tp);
ship.setX(row);
ship.setY(column);
System.out.println(ship.getX() + " " + ship.getY() + " " + ship.getPlayer());
ship.setHorizontal(horizontal);
this.placeShipIntoShipsArray(ship);
okToPlaceShipHere = false;
System.out.println("");
print();
}
}
/**
* Place the given ship into locations in the
* 2Darray that tracks ship positions.
* #param ship
*/
private void placeShipIntoShipsArray(Ships ship) {
int row = ship.getBowRow();
int column = ship.getBowColumn();
// player1.add.ship;
player1.removeAll(player1);
player2.removeAll(player2);
if (ship.isHorizontal()) {
for (int i=0; i < ship.getLength(); i++) {
this.ships[row][(column+i)] = ship;
}
}
else {
for (int i=0; i < ship.getLength(); i++) {
this.ships[(row+i)][column] = ship;
}
}
}
public void ifship(){
for (int i=0; i < 1; i++){
board();
}
}
private void placeShipIntoShipsArray2(Ships ship) {
int row = ship.getBowRow();
int column = ship.getBowColumn();
//player1.add.ships;
player1.removeAll(player1);
player2.removeAll(player2);
//ship.clear();
if (ship.isHorizontal()) {
for (int i=0; i < ship.getLength(); i++) {
this.ships2[row][(column+i)] = ship;
}
}
else {
for (int i=0; i < ship.getLength(); i++) {
this.ships2[(row+i)][column] = ship;
}
}
}
public void display() {
System.out.print(" ");
for (int i=0; i < 9; i++) {
System.out.print(i + " ");
}
System.out.print("\n");
for (int row=0; row < 6; row++) {
System.out.print(" " + row + " ");
for (int col=0; col < 9; col++) {
String value = "";
if (this.locationsFiredUpon[row][col]) {
value = "-";
}
if (this.ships2[row][col] != null) {
value = this.ships2[row][col].toString() ;
}
else {
value = "-";
}
System.out.print(value + " ");
}
System.out.print("\n");
}
remap();
}
boolean pr = false;
boolean pr2 = false;
public void moveShip(){
System.out.println("So you wanna move a ship");
System.out.println(player1);
for (int i=0; i > 1; i++) {
print();
System.out.println("map 1");
pr = true;
}
if (pr = true){
display();
}
//ArrayList<Ships> shipsToMove = new ArrayList<>();
ArrayList<Ships> shipsToMove = new ArrayList<>();
ArrayList<Ships> shipsToMove1 = player1;
boolean notMoved = false;
int rowM = 0;
int columnM = 0;
String Tp = "1";
boolean horizontal = false;
if(notMoved = false){
System.out.println("Occupardo, you no go here");
}
System.out.println("gets here 1");
for (Ships shipM : shipsToMove1) {
System.out.println("gets here 2");
while (!notMoved) {
Scanner scanner1 = new Scanner( System.in );
System.out.println("Enter a area to move to (e.g., 2,3)");
System.out.println("please enter a movement for the: " + shipM.getShipType() + shipM.getBowRow());
String[] coordinates = scanner1.nextLine().split(",");
if (coordinates.length != 2) {
System.out.println("Please enter coordinates in the correct format.");
continue;
}
rowM = Integer.parseInt(coordinates[0].trim());
columnM = Integer.parseInt(coordinates[1].trim());
// row = random.nextInt(6);
// column = random.nextInt(9);
horizontal = true;
notMoved = shipM.okToPlaceShipAt(rowM, columnM, horizontal, this);
}
if( notMoved = true){
this.bombOp(rowM, columnM);
}
shipM.setBowColumn(columnM);
shipM.setBowRow(rowM);
shipM.setHorizontal(horizontal);
this.placeShipIntoShipsArray2(shipM);
notMoved = false;
System.out.println("");
display();
}
}
public void moveShip2(ArrayList<Ships> player2){
System.out.println("So you wanna move a ship");
for (int i=0; i > 1; i++) {
display();
pr2 = true;
}
if (pr2 = true){
display();
}
ArrayList<Ships> shipsToMove = new ArrayList<>();
player2 = this.player2;
boolean notMoved = false;
int rowM = 0;
int columnM = 0;
String Tp = "1";
boolean horizontal = false;
if(notMoved = false){
System.out.println("Occupardo, you no go here");
}
System.out.println("gets here 1");
for (Ships ship : player2) {
System.out.println("gets here 2");
while (!notMoved) {
Scanner scanner1 = new Scanner( System.in );
System.out.println("Enter a area to move to (e.g., 2,3)");
System.out.println("please enter a movement for the: " + ship.getShipType());
String[] coordinates = scanner1.nextLine().split(",");
if (coordinates.length != 2) {
System.out.println("Please enter coordinates in the correct format.");
continue;
}
rowM = Integer.parseInt(coordinates[0].trim());
columnM = Integer.parseInt(coordinates[1].trim());
// row = random.nextInt(6);
// column = random.nextInt(9);
horizontal = true;
notMoved = ship.okToPlaceShipAt(rowM, columnM, horizontal, this);
}
if( notMoved = true){
this.bombOp(rowM, columnM);
}
ship.setBowColumn(columnM);
ship.setBowRow(rowM);
ship.setHorizontal(horizontal);
this.placeShipIntoShipsArray2(ship);
notMoved = false;
System.out.println("");
display();
display();
}
}
/**
* Print the current state of the game.
*/
public void print() {
System.out.print(" ");
for (int i=0; i < 9; i++) {
System.out.print(i + " ");
}
System.out.print("\n");
for (int row=0; row < 6; row++) {
System.out.print(" " + row + " ");
for (int col=0; col < 9; col++) {
String value = "";
if (this.locationsFiredUpon[row][col]) {
value = "-";
}
**if (this.ships[row][col] != null) {
value = this.ships[row][col].toString() ;**
}
if (this.locationsFiredUpon[row][col]) {
value = this.ships2[row][col].toString();
}
if (this.ships2[row][col] != null) {
value = this.ships2[row][col].toString() ;
}
else {
value = "-";
}
System.out.print(value + " ");
}
System.out.print("\n");
}
}
public void print2() {
System.out.print(" ");
for (int i=0; i < 9; i++) {
System.out.print(i + " ");
}
System.out.print("\n");
for (int row=0; row < 6; row++) {
System.out.print(" " + row + " ");
for (int col=0; col < 9; col++) {
String value = "";
if (this.locationsFiredUpon[row][col]) {
value = "-";
}
if (this.shipsM[row][col] != null) {
value = this.shipsM[row][col].toString() ;
}
if (this.locationsFiredUpon[row][col]) {
value = this.ships2[row][col].toString();
}
if (this.ships2[row][col] != null) {
value = this.ships2[row][col].toString() ;
}
else {
value = "-";
}
System.out.print(value + " ");
}
System.out.print("\n");
}
board();
}
/**
* Handle a shot fired at the specified position.
* #param row
* #param column
* #return true if a ship was hit; else false
*/
public boolean bombOp(int row, int column) {
this.shotsFired++;
this.locationsFiredUpon[row][column] = true;
Ships shipAtLocation = this.ships[row][column];
if (shipAtLocation.isSunk()) {
return false;
}
boolean shipWasHit = shipAtLocation.bombOp(row, column);
if (shipWasHit) {
this.hitCount++;
}
if (shipAtLocation instanceof Conflict) {
return shipWasHit;
}
if (shipAtLocation.isSunk()) {
shipsSunk++;
}
return shipWasHit;
}
The best way to debug NullPointerException is to look at the first line of the stack trace, which is:
NavalBattle.Board.print(Board.java:570)
What this means is that the error occurred on line number 570 in the Board.java file. You should go to this line in the file and look at which variables could be null on that line.
Line 570 is value = this.ships2[row][col].toString();. On this line, only 3 things can possibly be null:
this.ships2
`this.ships2[row]
`this.ships2[row][col]
If you cannot immediately see which of these is null, use your IDE to set a breakpoint there and start your program in debug mode. When the IDE stops at that line, create a "watch expression" for each of the above 3 expressions, or use the "evaluate expression" feature. One of them should be null.
Without debugging, I can only guess, but I think I can make a good guess. this.ship2 is unlikely to be null because I can see that you have initialised it in your code. I also don't think that this.ships2[row] is null - You have initialised the 2D array in the constructor correctly I think. Therefore, I think it is this.ships2[row][col] that is null, and calling toString() on null is throwing the NPE. To confirm my theory you could replace the line with:
value = String.valueOf(this.ships2[row][col]);
I'm writing a program for a class that uses data from a file (students' grades) and then averages and organizes it based on highest grade to lowest. I'm almost done except for an error at line 46, where it won't call the method:
findMaxIndex(courseGrade);
Any help would be greatly appreciated!
package project3;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
*
* #author badluckbowers
*/
public class Project3 {
final static int NUM_STUDENTS = 16;
public static String[] nameArray = new String[NUM_STUDENTS];
public static double[] labAvg = new double[NUM_STUDENTS];
public static double[] quizAvg = new double[NUM_STUDENTS];
public static double[] projectAvg = new double[NUM_STUDENTS];
public static double[] examAvg = new double[NUM_STUDENTS];
public static double[] finalExamArray = new double[NUM_STUDENTS];
public static double[] courseGrade = new double[NUM_STUDENTS];
public static char[] gradeArray = new char[NUM_STUDENTS];
/**
* #param args the command line arguments
*/
final static int numLabScores = 15;
final static int pointsLabPossible = 10;
final static int numQuizScores = 12;
final static int pointsQuizPossible = 5;
final static int numProjectScores = 6;
final static int pointsProjectPossible = 25;
final static int numExamScores = 2;
final static int pointsExamPossible = 100;
final static int numFinalExamScores = 1;
final static int pointsFinalExamPossible = 100;
public static void main(String[] args) throws FileNotFoundException {
readFile("scores.txt", nameArray, labAvg, quizAvg, projectAvg, examAvg, finalExamArray);
findMaxIndex(courseGrade);
printArray();
}
public static void readFile(String fileName, String[] nameArray, double[] labAvg, double[] quizAvg, double[] projectAvg, double[] examAvg, double[] finalExamArray) throws FileNotFoundException {
File input = new File(fileName);
if (!input.exists()) {
System.out.println("Error opening scores.txt for input; "
+ "aborting program run.");
System.exit(0);
}
Scanner inputFile = new Scanner(input);
for (int i = 0; i < NUM_STUDENTS; i++) {
nameArray[i] = inputFile.nextLine();
labAvg[i] = calculatePercent(inputFile, numLabScores, pointsLabPossible); //15-1
quizAvg[i] = calculatePercent(inputFile, numQuizScores, pointsQuizPossible); //12-1
projectAvg[i] = calculatePercent(inputFile, numProjectScores, pointsProjectPossible); //6-1
examAvg[i] = calculatePercent(inputFile, numExamScores, pointsExamPossible); //2-1
finalExamArray[i] = calculatePercent(inputFile, numFinalExamScores, pointsFinalExamPossible); //1-1
courseGrade[i] = calculateGrade(labAvg[i], quizAvg[i], projectAvg[i], examAvg[i], finalExamArray[i]);
gradeArray[i] = calculateLetter(courseGrade[i]);
inputFile.nextLine();
}
inputFile.close();
}
public static double calculatePercent(Scanner inFile, int numScores, int pointsPossible) {
double score;
double total = 0;
for (int i = 0; i < numScores; i++) {
score = inFile.nextDouble();
total += score;
}
return (total / (numScores * pointsPossible)) * 100;
}
public static double calculateGrade(double labAvg, double quizAvg, double projectAvg, double examAvg, double finalExamArray) {
return ((labAvg * .15 + quizAvg * .10 + projectAvg * .25 + examAvg * .30 + finalExamArray * .20));
}
public static char calculateLetter(double courseGrade) {
if (courseGrade < 60.0) {
return 'F';
} else if (courseGrade >= 60.0 && courseGrade < 70.0) {
return 'D';
} else if (courseGrade >= 70.0 && courseGrade < 80.0) {
return 'C';
} else if (courseGrade >= 80.0 && courseGrade < 90) {
return 'B';
}
return 'A';
}
//__________________________________________________________________________
// sort stuff
/**
* finds index of smallest element in the part of the array bounded by start
* and array.length-1
*
* #param courseGrade is fully populated
* #param start is index to begin searching for smallest element
* #return index of smallest item between start and array.length-1
* #throws java.io.FileNotFoundException
*/
public static double findMaxIndex(double[] courseGrade, int start) throws FileNotFoundException {
int maxIndex;
maxIndex = start;
for (int index = start + 1; index < courseGrade.length; index++) {
if (courseGrade[index] > courseGrade[maxIndex]) {
maxIndex = index;
}
}
return maxIndex;
}
/**
* the items in the array will be sorted largest to smallest
*
* #param courseGrade
* #throws java.io.FileNotFoundException
*/
public static void sortArray(double[] courseGrade) throws FileNotFoundException {
int maxIndex;
double maxItem;
for (int i = 0; i > courseGrade.length - 1; i++) {
maxIndex = (int) findMaxIndex(courseGrade, i);
//put the smaller item in place of the current item
maxItem = courseGrade[maxIndex];
courseGrade[maxIndex] = courseGrade[i];
courseGrade[i] = maxItem;
System.out.println("Array after pass " + (i + 1) + " of selection sort:");
for (int j = 0; j < courseGrade.length; j++) {
System.out.print(courseGrade[j] + " ");
}
System.out.println("");
}
}
//__________________________________________________________________________
public static void printArray() {
System.out.println("The array elements are: ");
for (int i = 0; i < nameArray.length; i++) {
System.out.println(nameArray[i] + " " + labAvg[i] + " " + quizAvg[i] + " " + projectAvg[i] + " " + examAvg[i] + " " + finalExamArray[i] + " " + courseGrade[i] + " " + gradeArray[i]);
}
System.out.println();
}
}
You need to pass second argument when calling the function findMaxIndex. Because your function definition has two parameters.
findMaxIndex(courseGrade, startIndex);
Does Apache Mahout provide a way to perform n-fold cross-validation, instead of the random hold-out test? If not, what other Java framework do you suggest (with available code samples / good documentation, and that you have personally used if possible)?
My current code (uses random hold-out):
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
double result = evaluator.evaluate(builder, null, model, 0.9, 1.0);
System.out.println("Evaluation : " + result);
Here is a custom implementation that I did extending the AbstractDifferenceRecommenderEvaluator from Mahout. I just copy and paste the code. Please check if it satisfy your needs. I think I have enough comments in the class.
public abstract class AbstractKFoldRecommenderEvaluator extends AbstractDifferenceRecommenderEvaluator {
private final Random random;
public double noEstimateCounterAverage = 0.0;
public double totalEstimateCount = 0.0;
public double totalEstimateCountAverage = 0.0;
private static final Logger log = LoggerFactory
.getLogger(AbstractKFoldRecommenderEvaluator.class);
public AbstractKFoldRecommenderEvaluator() {
super();
random = RandomUtils.getRandom();
}
public double getNoEstimateCounterAverage(){
return noEstimateCounterAverage;
}
public double getTotalEstimateCount(){
return totalEstimateCount;
}
public double getTotalEstimateCountAverage(){
return totalEstimateCountAverage;
}
/**
* We use the same evaluate function from the RecommenderEvaluator interface
* the trainingPercentage is used as the number of folds, so it can have
* values bigger than 0 to the number of folds.
*/
#Override
public double evaluate(RecommenderBuilder recommenderBuilder,
DataModelBuilder dataModelBuilder, DataModel dataModel,
double trainingPercentage, double evaluationPercentage)
throws TasteException {
Preconditions.checkNotNull(recommenderBuilder);
Preconditions.checkNotNull(dataModel);
Preconditions.checkArgument(trainingPercentage >= 0.0,
"Invalid trainingPercentage: " + trainingPercentage);
Preconditions.checkArgument(evaluationPercentage >= 0.0
&& evaluationPercentage <= 1.0,
"Invalid evaluationPercentage: " + evaluationPercentage);
log.info("Beginning evaluation using {} of {}", trainingPercentage,
dataModel);
int numUsers = dataModel.getNumUsers();
// Get the number of folds
int noFolds = (int) trainingPercentage;
// Initialize buckets for the number of folds
List<FastByIDMap<PreferenceArray>> folds = new ArrayList<FastByIDMap<PreferenceArray>>();
for (int i = 0; i < noFolds; i++) {
folds.add(new FastByIDMap<PreferenceArray>(
1 + (int) (i / noFolds * numUsers)));
}
// Split the dataModel into K folds per user
LongPrimitiveIterator it = dataModel.getUserIDs();
while (it.hasNext()) {
long userID = it.nextLong();
if (random.nextDouble() < evaluationPercentage) {
splitOneUsersPrefs2(noFolds, folds, userID, dataModel);
}
}
double result = Double.NaN;
List<Double> intermediateResults = new ArrayList<>();
List<Integer> unableToRecoomend = new ArrayList<>();
List<Integer> averageEstimateCounterIntermediate = new ArrayList<>();
noEstimateCounterAverage = 0.0;
totalEstimateCount = 0.0;
totalEstimateCountAverage = 0.0;
int totalEstimateCounter = 0;
// Rotate the folds. Each time only one is used for testing and the rest
// k-1 folds are used for training
for (int k = 0; k < noFolds; k++) {
FastByIDMap<PreferenceArray> trainingPrefs = new FastByIDMap<PreferenceArray>(
1 + (int) (evaluationPercentage * numUsers));
FastByIDMap<PreferenceArray> testPrefs = new FastByIDMap<PreferenceArray>(
1 + (int) (evaluationPercentage * numUsers));
for (int i = 0; i < folds.size(); i++) {
// The testing fold
testPrefs = folds.get(k);
// Build the training set from the remaining folds
if (i != k) {
for (Map.Entry<Long, PreferenceArray> entry : folds.get(i)
.entrySet()) {
if (!trainingPrefs.containsKey(entry.getKey())) {
trainingPrefs.put(entry.getKey(), entry.getValue());
} else {
List<Preference> userPreferences = new ArrayList<Preference>();
PreferenceArray existingPrefs = trainingPrefs
.get(entry.getKey());
for (int j = 0; j < existingPrefs.length(); j++) {
userPreferences.add(existingPrefs.get(j));
}
PreferenceArray newPrefs = entry.getValue();
for (int j = 0; j < newPrefs.length(); j++) {
userPreferences.add(newPrefs.get(j));
}
trainingPrefs.remove(entry.getKey());
trainingPrefs.put(entry.getKey(),
new GenericUserPreferenceArray(
userPreferences));
}
}
}
}
DataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(
trainingPrefs) : dataModelBuilder
.buildDataModel(trainingPrefs);
Recommender recommender = recommenderBuilder
.buildRecommender(trainingModel);
Double[] retVal = getEvaluation(testPrefs, recommender);
double intermediate = retVal[0];
int noEstimateCounter = ((Double)retVal[1]).intValue();
totalEstimateCounter += ((Double)retVal[2]).intValue();
averageEstimateCounterIntermediate.add(((Double)retVal[2]).intValue());
log.info("Evaluation result from fold {} : {}", k, intermediate);
log.info("Average Unable to recommend for fold {} in: {} cases out of {}", k, noEstimateCounter, ((Double)retVal[2]).intValue());
intermediateResults.add(intermediate);
unableToRecoomend.add(noEstimateCounter);
}
double sum = 0;
double noEstimateSum = 0;
double totalEstimateSum = 0;
// Sum the results in each fold
for (int i = 0; i < intermediateResults.size(); i++) {
if (!Double.isNaN(intermediateResults.get(i))) {
sum += intermediateResults.get(i);
noEstimateSum+=unableToRecoomend.get(i);
totalEstimateSum+=averageEstimateCounterIntermediate.get(i);
}
}
if (sum > 0) {
// Get an average for the folds
result = sum / intermediateResults.size();
}
double noEstimateCount = 0;
if(noEstimateSum>0){
noEstimateCount = noEstimateSum / unableToRecoomend.size();
}
double avgEstimateCount = 0;
if(totalEstimateSum>0){
avgEstimateCount = totalEstimateSum / averageEstimateCounterIntermediate.size();
}
log.info("Average Evaluation result: {} ", result);
log.info("Average Unable to recommend in: {} cases out of avg. {} cases or total {} ", noEstimateCount, avgEstimateCount, totalEstimateCounter);
noEstimateCounterAverage = noEstimateCount;
totalEstimateCount = totalEstimateCounter;
totalEstimateCountAverage = avgEstimateCount;
return result;
}
/**
* Split the preference values for one user into K folds, randomly
* Generate random number until is not the same as the previously generated on
* in order to make sure that at least two buckets are populated.
*
* #param k
* #param folds
* #param userID
* #param dataModel
* #throws TasteException
*/
private void splitOneUsersPrefs(int k,
List<FastByIDMap<PreferenceArray>> folds, long userID,
DataModel dataModel) throws TasteException {
List<List<Preference>> oneUserPrefs = Lists
.newArrayListWithCapacity(k + 1);
for (int i = 0; i < k; i++) {
oneUserPrefs.add(null);
}
PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
int size = prefs.length();
int previousBucket = -1;
Double rand = -2.0;
for (int i = 0; i < size; i++) {
Preference newPref = new GenericPreference(userID,
prefs.getItemID(i), prefs.getValue(i));
do {
rand = random.nextDouble() * k * 10;
rand = (double) Math.floor(rand / 10);
// System.out.println("inside Rand "+rand);
} while (rand.intValue() == previousBucket);
// System.out.println("outside rand "+rand);
if (oneUserPrefs.get(rand.intValue()) == null) {
oneUserPrefs.set(rand.intValue(), new ArrayList<Preference>());
}
oneUserPrefs.get(rand.intValue()).add(newPref);
previousBucket = rand.intValue();
}
for (int i = 0; i < k; i++) {
if (oneUserPrefs.get(i) != null) {
folds.get(i).put(userID,
new GenericUserPreferenceArray(oneUserPrefs.get(i)));
}
}
}
/**
* Split the preference values for one user into K folds, by shuffling.
* First Shuffle the Preference array for the user. Then distribute the item-preference pairs
* starting from the first buckets to the k-th bucket, and then start from the beggining.
*
* #param k
* #param folds
* #param userID
* #param dataModel
* #throws TasteException
*/
private void splitOneUsersPrefs2(int k, List<FastByIDMap<PreferenceArray>> folds, long userID, DataModel dataModel) throws TasteException {
List<List<Preference>> oneUserPrefs = Lists.newArrayListWithCapacity(k + 1);
for (int i = 0; i < k; i++) {
oneUserPrefs.add(null);
}
PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
int size = prefs.length();
List<Preference> userPrefs = new ArrayList<>();
Iterator<Preference> it = prefs.iterator();
while (it.hasNext()) {
userPrefs.add(it.next());
}
// Shuffle the items
Collections.shuffle(userPrefs);
int currentBucket = 0;
for (int i = 0; i < size; i++) {
if (currentBucket == k) {
currentBucket = 0;
}
Preference newPref = new GenericPreference(userID, userPrefs.get(i).getItemID(), userPrefs.get(i).getValue());
if (oneUserPrefs.get(currentBucket) == null) {
oneUserPrefs.set(currentBucket, new ArrayList<Preference>());
}
oneUserPrefs.get(currentBucket).add(newPref);
currentBucket++;
}
for (int i = 0; i < k; i++) {
if (oneUserPrefs.get(i) != null) {
folds.get(i).put(userID, new GenericUserPreferenceArray(oneUserPrefs.get(i)));
}
}
}
private Double[] getEvaluation(FastByIDMap<PreferenceArray> testPrefs, Recommender recommender) throws TasteException {
reset();
Collection<Callable<Void>> estimateCallables = Lists.newArrayList();
AtomicInteger noEstimateCounter = new AtomicInteger();
AtomicInteger totalEstimateCounter = new AtomicInteger();
for (Map.Entry<Long, PreferenceArray> entry : testPrefs.entrySet()) {
estimateCallables.add(new PreferenceEstimateCallable(recommender, entry.getKey(), entry.getValue(), noEstimateCounter, totalEstimateCounter));
}
log.info("Beginning evaluation of {} users", estimateCallables.size());
RunningAverageAndStdDev timing = new FullRunningAverageAndStdDev();
execute(estimateCallables, noEstimateCounter, timing);
Double[] retVal = new Double[3];
retVal[0] = computeFinalEvaluation();
retVal[1] = (double) noEstimateCounter.get();
retVal[2] = (double) totalEstimateCounter.get();
//retVal.put(computeFinalEvaluation(), noEstimateCounter.get());
//return computeFinalEvaluation();
return retVal;
}}
And here is actual implementation class:
public class RMSRecommenderEvaluatorModified extends AbstractKFoldRecommenderEvaluator {
private RunningAverage average;
#Override
protected void reset() {
average = new FullRunningAverage();
}
#Override
protected void processOneEstimate(float estimatedPreference, Preference realPref) {
double diff = realPref.getValue() - estimatedPreference;
average.addDatum(diff * diff);
}
#Override
protected double computeFinalEvaluation() {
return Math.sqrt(average.getAverage());
}
#Override
public String toString() {
return "RMSRecommenderEvaluator";
}}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
How could I get the program to output all the information? IT currently returns a NullPointException error. Thanks.
I am supposed to use the delete methods just as they are, I cannot change them, but I am sure there must be something I can do.
public class TestCandidate7
{
public static int getTotal(Candidate[] election)
{
int total = 0;
for(Candidate candidate : election )
{
total += candidate.numVotes;
}
return total;
}
public static void printResults(Candidate[] election)
{
double percent;
System.out.println("Candidate Votes Received % of Total Votes");
for (int x = 0; x < election.length; x++)
{
percent = (double) (election[x].votes()) / getTotal(election) * 100;
System.out.printf("%-15s %10d %20.0f", election[x].getName(), election[x].votes(), percent);
System.out.println();
}
}
public static void deleteByLoc(Candidate[] election,
int location)
{
if ((location > 0) && (location < election.length))
{
//move items up in the array -
for(int index = location; index < election.length -1; index++)
election[index] = election[index + 1];
election[election.length-1] = null;
}
}
public static void deleteByName(Candidate[] election,
String find)
{
int location = 0;
int index;
// find location of item you want to delete
for(index = 0; index < election.length; index++)
if ((election[index] != null) && (election[index].getName().equals(find)))
{
location = index;
break;
}
else if (election[index] == null)
{
location = -1;
break;
}
if ((index != election.length) && (location >= 0))
{ //move items up in the array
for(index = location; index < election.length -1; index++)
election[index] = election[index + 1];
election[election.length-1] = null;
}
}
public static void main(String[] args)
{
Candidate[] election = new Candidate[10];
// create election
election[0] = new Candidate("John Smith", 5000);
election[1] = new Candidate("Mary Miller", 4000);
election[2] = new Candidate("Michael Duffy", 6000);
election[3] = new Candidate("Tim Robinson", 2500);
election[4] = new Candidate("Joe Ashtony", 1800);
election[5] = new Candidate("Mickey Jones", 3000);
election[6] = new Candidate("Rebecca Morgan", 2000);
election[7] = new Candidate("Kathleen Turner", 8000);
election[8] = new Candidate("Tory Parker", 500);
election[9] = new Candidate("Ashton Davis", 10000);
System.out.println("Original results:");
System.out.println();
printResults(election);
System.out.println();
System.out.println("Total of votes in election: " + getTotal(election) );
System.out.println();
deleteByLoc(election, 6);
System.out.println("Deleted location 6:");
System.out.println();
printResults(election);
System.out.println();
System.out.println("Total of votes in election: " + getTotal(election) );
System.out.println();
deleteByName(election, "Kathleen Turner");
System.out.println("Deleted Kathleen Turner:");
System.out.println();
printResults(election);
System.out.println();
System.out.println("Total of votes in election: " + getTotal(election) );
System.out.println();
}
}
Candidate
public class Candidate
{
// instance variables
int numVotes;
String name;
/**
* Constructor for objects of class InventoryItem
*/
public Candidate(String n, int v)
{
// initialise instance variables
name = n;
numVotes = v;
}
public int votes()
{
return numVotes;
}
public void setVotes(int num)
{
numVotes = num;
}
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
}
public String toString()
{
return name + " received " + numVotes + " votes.";
}
}
When you "delete" array elements, after the shift you assign null to the most right element of the array.
In your getTotal() you traverse the entire array and retrieve the value of numVotes for each element. When you reach the null element you are getting the exception since null does not have any fields..
This is the code I currently have. For some reason, I keep getting and error called: NoSuchElementException: No line found. The exception occurs at the line:
"String number = scanPhone.nextLine();" and in the Provider class and at the line:"provObj.readCellPhoneFile(fileNameIn);"in the CellPhonesPart2 class. Does anyone know what's wrong with it?
import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
import java.io.IOException;
public class Provider {
private String name;
private CellPhone[] phones;
private String[] excludedRecords;
/**
* Constructor for Provider class.
*/
public Provider() {
name = "not yet assigned";
phones = new CellPhone[0];
excludedRecords = new String[0];
}
/**
* Reads in file name and assigns data.
*
* #param fileNameIn Input for file name from main
* #throws IOException from scanning file name
*/
public void readCellPhoneFile(String fileNameIn) throws IOException {
//Reads in file name and creates Scanner object
File fileIn = new File(fileNameIn);
Scanner scanFile = new Scanner(fileIn);
//Assigns name from first line
name = scanFile.nextLine();
//Assigns data from file to different categories
while (scanFile.hasNext()) {
Scanner scanPhone = new Scanner(scanFile.nextLine());
scanPhone.useDelimiter(", *");
String phoneType = scanPhone.nextLine();
char phoneChar = phoneType.toUpperCase().charAt(0);
//Assigns phone to different category
switch (phoneChar) {
case 'F':
String number = scanPhone.nextLine();
int texts = Integer.parseInt(scanPhone.nextLine());
int minutes = Integer.parseInt(scanPhone.nextLine());
FlipPhone flip1 = new FlipPhone(number, texts, minutes);
addPhone(flip1);
break;
case 'S':
number = scanPhone.nextLine();
texts = Integer.parseInt(scanPhone.nextLine());
minutes = Integer.parseInt(scanPhone.nextLine());
int data = Integer.parseInt(scanPhone.nextLine());
SmartPhone smart1 = new SmartPhone(number, texts, minutes, data);
addPhone(smart1);
break;
case 'I':
number = scanPhone.nextLine();
texts = Integer.parseInt(scanPhone.nextLine());
minutes = Integer.parseInt(scanPhone.nextLine());
data = Integer.parseInt(scanPhone.nextLine());
int iMessages = Integer.parseInt(scanPhone.nextLine());
IPhone iPhone1 = new IPhone(number, texts,
minutes, data, iMessages);
addPhone(iPhone1);
break;
case 'A':
number = scanPhone.nextLine();
texts = Integer.parseInt(scanPhone.nextLine());
minutes = Integer.parseInt(scanPhone.nextLine());
data = Integer.parseInt(scanPhone.nextLine());
int hotspotMin = Integer.parseInt(scanPhone.nextLine());
Android android1 = new Android(number, texts,
minutes, data, hotspotMin);
addPhone(android1);
break;
default:
String unrecognized = scanPhone.nextLine();
addExcludedRecord(unrecognized);
}
}
}
/**
* Returns string for provider name.
*
* #return String
*/
public String getName() {
return name;
}
/**
* Assigns a name input as provider name.
*
* #param nameIn Input for provider name
*/
public void setName(String nameIn) {
name = nameIn;
}
/**
* Returns CellPhone array for phones.
*
* #return CellPhone[]
*/
public CellPhone[] getPhones() {
return phones;
}
/**
* Returns string array for excluded records.
*
* #return String[]
*/
public String[] getExcludedRecords() {
return excludedRecords;
}
/**
* Adds phone to array of phones.
*
* #param newPhoneIn Input for phone object
*/
public void addPhone(CellPhone newPhoneIn) {
//Increases size of phones array
CellPhone[] newPhones = new CellPhone[phones.length + 1];
for (int i = 0; i < phones.length; i++) {
newPhones[i] = phones[i];
}
phones = newPhones;
//Adds CellPhone object to phones array
phones[phones.length] = newPhoneIn;
}
/**
* Determines if phone number is found and deleted.
*
* #return boolean
* #param numberIn Input for phone number
*/
public boolean deletePhone(String numberIn) {
boolean delete = false;
int deleteIndex = -1;
//Searches for phone number match
for (int i = 0; i < phones.length; i++) {
if (numberIn == phones[i].getNumber()) {
deleteIndex = i;
//Decreases size of phones array
CellPhone[] newPhones = new CellPhone[phones.length - 1];
for (i = 0; i < phones.length; i++) {
newPhones[i] = phones[i];
}
phones = newPhones;
}
}
if (deleteIndex > -1) {
for (int i = deleteIndex; i < phones.length - 1; i++) {
phones[i] = phones[i + 1];
}
return true;
}
else {
return false;
}
}
/**
* Adds unrecognized phone to excluded records.
*
* #param excRecIn Input for unrecognized phone
*/
public void addExcludedRecord(String excRecIn) {
//Increases capacity of excludedRecords
String[] newExcRecords = new String[excludedRecords.length + 1];
for (int i = 0; i < excludedRecords.length; i++) {
newExcRecords[i] = excludedRecords[i];
}
excludedRecords = newExcRecords;
//Adds excRecIn to array
excludedRecords[excludedRecords.length] = excRecIn;
}
/**
* Returns list of cell phones in phones array.
*
* #return String
*/
public String toString() {
String result = "";
for (CellPhone phone : phones) {
result += phone;
}
return result;
}
/**
* Calculates total bill for all phones.
*
* #return double
*/
public double calculateTotalBill() {
double totalBill = 0;
for (int i = 0; i < phones.length; i++) {
totalBill += phones[i].calculateBill();
}
return totalBill;
}
/**
* Calculates total number of texts for all phones.
*
* #return int
*/
public int calculateTotalTexts() {
int totalTexts = 0;
for (int i = 0; i < phones.length; i++) {
totalTexts += phones[i].getTexts();
}
return totalTexts;
}
/**
* Calculates total number of minutes for all phones.
*
* #return int
*/
public int calculateTotalMinutes() {
int totalMinutes = 0;
for (int i = 0; i < phones.length; i++) {
totalMinutes += phones[i].getMinutes();
}
return totalMinutes;
}
/**
* Calculates total data for smartphones.
*
* #return int
*/
public int calculateTotalData() {
int totalData = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof SmartPhone) {
totalData += ((SmartPhone) phones[i]).getData();
}
}
return totalData;
}
/**
* Calculates total hotspot minutes for Androids.
*
* #return int
*/
public int calculateTotalHotspotMin() {
int totalHotspotMin = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof Android) {
totalHotspotMin += ((Android) phones[i]).getHotspotMin();
}
}
return totalHotspotMin;
}
/**
* Calculates total iMessage count for iPhones.
*
* #return int
*/
public int calculateTotalIMessages() {
int totalIMessages = 0;
for (int i = 0; i < phones.length; i++) {
if (phones[i] instanceof IPhone) {
totalIMessages += ((IPhone) phones[i]).getIMessages();
}
}
return totalIMessages;
}
/**
* Returns string for summary report.
*
* #return String
*/
public String summary() {
String summary = "------------------------------"
+ "\nSummary for " + getName()
+ "\n------------------------------"
+ "\nNumber of cell phones: " + getPhones()
+ "Texts: " + calculateTotalTexts()
+ "Talk Minutes: " + calculateTotalMinutes()
+ "Data: " + calculateTotalData()
+ "Hotspot Minutes: " + calculateTotalHotspotMin()
+ "iMessages: " + calculateTotalIMessages()
+ "Bill Total: $" + calculateTotalBill()
+ "\n\n------------------------------"
+ "\nRates for " + getName()
+ "\n------------------------------"
+ rates()
+ "\n------------------------------"
+ "\nCell Phones by Number"
+ "\n------------------------------\n"
+ listByNumber()
+ "\n------------------------------"
+ "\nCell Phones by Billing Amount"
+ "\n------------------------------\n"
+ listByBill()
+ "\n------------------------------"
+ "\nExcluded Records"
+ "\n------------------------------\n"
+ excludedRecordsList();
return summary;
}
/**
* Returns string for different rates.
*
* #return String
*/
public String rates() {
String rates = "FlipPhone Talk Rate: $" + FlipPhone.TALK_RATE
+ "\tText Rate: $" + FlipPhone.TEXT_RATE
+ "SmartPhone Talk Rate: $" + SmartPhone.TALK_RATE
+ "\tText Rate: $" + SmartPhone.TEXT_RATE
+ "\tMax Talk Time: " + SmartPhone.MAX_TALK_TIME
+ "\n\tiPhone iMessage Rate: $" + IPhone.IMESSAGE_RATE
+ "\n\tAndroid HotspotRate: $" + Android.HOTSPOT_RATE;
return rates;
}
/**
* Returns string of phones sorted by number.
*
* #return String
*/
public String listByNumber() {
String listByNumber = "";
for (CellPhone phone : phones) {
listByNumber += phone.toString();
}
Arrays.sort(phones);
return listByNumber;
}
/**
* Returns string of phones sorted by bill.
*
* #return String
*/
public String listByBill() {
String listByBill = "";
for (CellPhone phone : phones) {
listByBill += phone.toString();
}
Arrays.sort(phones, new CellPhoneBillComparator());
return listByBill;
}
/**
* Returns string excluded records.
*
* #return String
*/
public String excludedRecordsList() {
String excRecList = "";
for (String phone : excludedRecords) {
excRecList += phone;
}
return excRecList;
}
}
It reads in the file from this class:
public class CellPhonesPart2 {
/**
* Creates objects from different classes and prints objects.
*
* #param args Reads in file
* #throws IOException from scanning input file
*/
public static void main(String[] args) throws IOException {
String fileNameIn = args[0];
Provider provObj = new Provider();
provObj.readCellPhoneFile(fileNameIn);
System.out.println(provObj.summary());
}
}
Scanner scanPhone = new Scanner(scanFile.nextLine());
// this is causing your error. scanPhone is ultimately just a one line String
// this line will be found
String phoneType = scanPhone.nextLine();
// this line won't because scanPhone is only one line
String number = scanPhone.nextLine();
Edit: possible Solution
while (scanFile.hasNextLine()) {
Scanner scanPhone = new Scanner(scanFile.nextLine());
scanPhone.useDelimiter(", *");
String phoneType = scanPhone.next();
char phoneChar = phoneType.toUpperCase().charAt(0);
//Assigns phone to different category
switch (phoneChar) {
case 'F':
String number = scanPhone.next();
int texts = Integer.parseInt(scanePhone.next());
int minutes = Integer.parseInt(scanPhone.next());
FlipPhone flip1 = new FlipPhone(number, texts, minutes);
addPhone(flip1);
break;
Changed all the scanPhone.nextLine()'s to scanPhone.next()
Also, try using while (scanFile.hasNextLine()); instead of hasNext()
you should use an appropriate hasNext() before calling nextLine();
Scanner may be empty.!