Cannot read text file into array and write to text file again - java

This my whole code.
I want to make a simple program that will read a
text file and put it to array then write it to the
same text file,
also can add and delete the existing input and my input.
Problem
The delete and writer part seems not working, only blank text file when I run the code
These are the error after I select the exit.
java.lang.NullPointerException at ContactList.writer(ContactList.java:51) at
ContactListDriver.main(ContactListDriver.java:73) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:27‌​2)
public class Contact {
//Each contact stores the name, phone number, and email address
private String name;
private String number;
private String email;
public Contact(String name, String number, String email)
{
this.name = name;
this.number = number;
this.email = email;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String getEmail()
{
return email;
}
public void setName(String name)
{
this.name = name;
}
public void setNumber(String number)
{
this.number = number;
}
public void setEmail(String email)
{
this.email = email;
}
}
class for processing the inputs.
import java.io.*;
import java.lang.*;
import java.util.*;
public class ContactList {
public Contact[] myContacts;
public static final int MAX = 100;
private int numContacts;
public ContactList()
{
myContacts = new Contact[MAX];
numContacts = 0;
}
public void addContact(String name, String number, String email)
{
Contact c = new Contact(name, number, email);
myContacts[numContacts] = c;
numContacts++;
}
public void deleteContact(String name)
{
for ( int i = 0; i <= numContacts-1 ; i++){
if( name == myContacts[i].getName())
{
myContacts[i] = null;
break;
}
}
numContacts--;
}
public void writer(){
String x = "MyContacts.txt";
try {
PrintWriter outputs = new PrintWriter(x);
for( int i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(c!=null){ // check if c is null before writing to file
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
}
}
outputs.close();
}catch (IOException e) {
e.printStackTrace();
}
catch(NullPointerException ex){
}
}
public void displayContacts()
{
int i;
for(i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(null != c){
System.out.println("Name: " + c.getName());
System.out.println("Number: " + c.getNumber());
System.out.println("Email: " + c.getEmail());
System.out.println("------------------------------------");
}
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
The Driver....
public class ContactListDriver {
public static void main(String[] args) throws FileNotFoundException
{
ContactList cList = new ContactList();
File in = new File("MyContacts.txt");
Scanner sc = new Scanner(in);
int option;
char again = 'n';
String name = null;
String number = null;
String email = null;
while(sc.hasNext())
{
//read one line from text file
String entry = sc.nextLine();
//System.out.println(entry);
String[] con = entry.split("\\s+");
//System.out.println(con[0] + " " + con[1] + " " + con[2]);
cList.addContact(con[0], con[1], con[2]);
}
Scanner userIn = new Scanner(System.in);
do{
displayOptions();
option = userIn.nextInt();
switch(option)
{
case 1:
System.out.println(" Name > ");
name = userIn.next();
System.out.println(" Number > ");
number = userIn.next();
System.out.println(" Email Address > ");
email = userIn.next();
cList.addContact(name, number, email);
break;
case 2:
//delete contact
System.out.println("Contact Name > ");
name = userIn.next();
cList.deleteContact(name);
break;
case 3:
//display contact
cList.displayContacts();
break;
case 4:
cList.writer();
System.out.println(" are you sure ? press y ");
String x = userIn.next();
again = x.charAt(0);
break;
}
}while( again == 'n' );
}
private static void displayOptions() {
System.out.println("(1) Add");
System.out.println("(2) Delete");
System.out.println("(3) Show Contacts");
System.out.println("(4) Exit");
}
}

One problem I see is:
You have a extra break; statement inside deleteContact(String name) function
and String comparision name == myContacts[i].getName() should be name.equals(myContacts[i].getName())
public void deleteContact(String name)
{
for ( int i = 0; i <= numContacts-1; i++){
if( name.equals( myContacts[i].getName()))// string comparison uses equals();
{
myContacts[i] = null;
numContacts--; // this line should be inside of if condition
break;
}
// break; No need of breaking the loop here
}
}
Another problem is at writer() function
public void writer(){
String x = "MyContacts.txt";
try {
PrintWriter outputs = new PrintWriter(x);
for( int i=0; i < myContacts.length; i++)
{
Contact c = myContacts[i];
if(c!=null){ // check if c is null before writing to file
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
}
}
outputs.close();
}catch (IOException e) {
e.printStackTrace();
}
catch(NullPointerException ex){ // Or just catch the NPE
}

You have declared and initialized the Contact array of size MAX. but,it seems to be that you haven't initialized the elements though. i.e. c is null in the below code
Contact c = myContacts[i];
outputs.println(""+c.getName()+" "+c.getNumber()+" "+c.getName());
outputs.flush();
myContacts[i] should return a Contact instance. As said by Meno, there are lot of other problems in your code. You have to always cover all the possible scenarios while writing the code.

Most importantly you need to fix the ContactList class. It is inserting new elements into the last index, and deleting at any location using the name.
For example, let's say the ContactList has three elements in it at 0, 1 and 2 indexes. So numContacts is set to 3.
Now ContactList has elements as:
[0]C0, [1]C1, [2]C2, [3]null, ...
Then if the contact at 0 index is deleted (set to null), then numContacts is set to 2.
Now the ContactList has elements as:
[0]null, [1]C1, [2]C2, [3] null, ...
A new insert will be added to the index 2, and it will override the C2 value.
Simplest solution is to use an ArrayList instead of an array.
As others have mentioned there are few more issues to fix, but above is the most important in my opinion.

There are many issues with your code so not easy to say where to begin.
First: Your public void deleteContact(String name)-method is broken. It compares Strings using == instead of equals(). And worse: It creates null pointers mid in your array which will cause problems in your writer()-method.
Second: Why do you use arrays? You should use java.util.ArrayList which offers out-of-the-box implementations for adding, getting and deleting contacts.
Third: If you are missing your text file, you might have overlooked it because of missing path so you don't know where to look for this file. So please add a full path to file name.
Fourth: I would also use scanner.hasNextLine() instead of scanner.hasNext() if you then call scanner.nextLine().
Since you said you are not allowed to use ArrayList you should study its source code especially for removing elements. It does not only nullify the array bucket, but also to shift all following elements one index backwards so you don't have any null gap until the index given by element count. And two breaks in deleteContact()-method are really not necessary.

Related

How can I create a "high score list" on a txt file which stores top 10 scores and names of the players who scored them?

I need to make high score list in a txt file. In the first game, the txt file should be empty as it is the first game. After the first game, the score list must be updated each time with the player's name and the player's score. The list should of course be ordered from high to low according to player's score. After 10 games, the last ones should be removed and only 10 should remain in the list.
I am trying to do this but every time my txt file is stays empty. How can I fix this issue?
My HighScore class:
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.Formatter;
import java.nio.file.Paths;
public class HighScore {
public class HighScoreEntry {
private String name;
private int score;
public HighScoreEntry(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
}
public void writeHighScores(HighScoreEntry[] highScores) {
Formatter f = null;
FileWriter fw = null;
try {
fw = new FileWriter("highscores.txt",true);
f = new Formatter(fw);
for (int i = 0; i < highScores.length; i++) {
f.format("%s:%d%n", highScores[i].getName(), highScores[i].getScore());
}
} catch (IOException e) {
System.out.println("An error occurred while writing the high scores file.");
} finally {
if (f != null) {
f.close();
}
}
}
public HighScoreEntry[] readHighScores() {
HighScoreEntry[] highScores = new HighScoreEntry[10];
// Initialize the high scores array with default values
for (int i = 0; i < highScores.length; i++) {
highScores[i] = new HighScoreEntry("", 0);
}
Scanner reader = null;
try {
reader = new Scanner(Paths.get("highscores.txt"));
int i = 0;
while (reader.hasNextLine() && i < 10) {
String line = reader.nextLine();
String[] parts = line.split(":");
String name = parts[0];
int score = Integer.parseInt(parts[1]);
highScores[i] = new HighScoreEntry(name, score);
i++;
}
} catch (IOException e) {
System.out.println("An error occurred while reading the high scores file.");
} finally {
if (reader != null) {
reader.close();
}
}
return highScores;
}
public void updateHighScores(String name, int score) {
System.out.println("Updating high scores with name " + name + " and score " + score);
// Write the player's score and name to the high scores file
writeHighScores(new HighScoreEntry[] {new HighScoreEntry(name, score)});
// Read the high scores from the file
HighScoreEntry[] highScores = readHighScores();
// Sort the high scores
sortHighScores(highScores);
}
private void sortHighScores(HighScoreEntry[] highScores) {
for (int i = 0; i < highScores.length - 1; i++) {
for (int j = i + 1; j < highScores.length; j++) {
if (highScores[i].getScore() < highScores[j].getScore()) {
HighScoreEntry temp = highScores[i];
highScores[i] = highScores[j];
highScores[j] = temp;
}
}
}
}
}
My calling method in Game class:
HighScore highScore = new HighScore();
highScore.updateHighScores(user, playerPoints);
I just have to use them. I can't use anything other than these.
The Formatter class returns a formatted string, but you're not capturing the return value of your format call, nor are you writing the resulting string to your FileWriter.
It should look something like this:
String result = f.format("%s:%d%n", highScores[i].getName(), highScores[i].getScore());
fw.write(string);
Give or take a newline.

ArrayIndexOutOfBounds Exception Error When Displaying Reservations After Booking - Java

I'm making a reservation feature for my events, and I can successfully add the attendee, however when I want to display the details for every attendee, it gives me a ArrayIndexOutOfBounds exception error, which I'm not quite sure how to fix.
Main.java
private static Scanner sc = new Scanner(System.in);
private static int eventCreationLimit = 5;
private static Event[] events = new Event[eventCreationLimit];
private static int eventsCreated;
public static void main(String args[]) {
String input;
// Main menu.
do {
System.out.println("\n~ BOOKING SYSTEM ~");
System.out.println("------------------");
System.out.println("A. Schedule an Event");
System.out.println("B. Add an Attendee");
System.out.println("C. View Reservations");
System.out.println("X. Exit\n");
System.out.print("Select an option: ");
input = sc.nextLine();
switch (input.toUpperCase()) {
case "A":
scheduleAnEvent();
break;
case "B":
addAttendee();
break;
case "C":
displayReservations();
break;
case "X":
System.out.println("INFO: You have exited the booking system.");
break;
default:
System.out.println("ERROR: Invalid input!");
}
} while (!input.equalsIgnoreCase("X"));
}
private static void scheduleAnEvent() {
System.out.println("\n~ SCHEDULE A EVENT ~");
System.out.println("--------------------");
System.out.print("Enter the ID: ");
String ID = sc.nextLine();
...
System.out.print("Enter the attendee limit: ");
int attendeeLimit = Integer.parseInt(sc.nextLine());
// Add the new event to the array.
events[eventsCreated++] = new Event(ID, ..., attendeeLimit, attendeeLimit, ...);
for (int i = 0; i < eventsCreated; i++)
// Set the places available for the specific event being created to subtract it later when an attendee is added.
if (ID.equals(events[i].getID()))
// The number of places available left in the event can be displayed by going to "B. View All Events".
events[i].setPlacesAvailable(attendeeLimit);
// Give the user a confirmation message.
System.out.println("\nINFO: Sucessfully created Event: " + ID + ".");
}
private static void addAttendee() {
Event event = null;
boolean result = false;
System.out.println("\n~ ADD AN ATTENDEE ~");
System.out.println("-------------------");
System.out.print("Enter attendee name: ");
String name = sc.nextLine();
System.out.print("Enter attendee phone number: ");
String phone = sc.nextLine();
Attendee a = new Attendee(name, phone);
System.out.print("Enter event ID: ");
String eventID = sc.nextLine();
// Check if the given ID matches an event.
for (int i = 0; i < eventsCreated; i++)
if (events[i].getID().equals(eventID))
event = events[i];
if (event != null) {
if (event.getID().equals(eventID)) {
result = ((Event) event).addAttendee(a);
if (result) {
// If the event has enough room, then add the attendee.
System.out.println("INFO: Attendee successfully added to Event: " + eventID + ".");
displayReservations();
}
else
// If the event is full, then the attendee will not be added.
System.out.println("ERROR: The Event: " + eventID + " is full, the attendee could not be added.");
} else
System.out.println("ERROR: The given ID does not match any existing event.");
} else
System.out.println("ERROR: The event was not found.");
}
private static void displayReservations() {
System.out.println("\n~ RESERVATIONS ~");
System.out.println("----------------");
String pattern = "%-18s %-18s %-22s %-1s\n";
System.out.printf(pattern, "NAME", "PHONE", "EVENT ID", "FEE");
System.out.println("----------------------------------------------------------------");
// Display all reservations for events.
for (int i = 0; i < events[i].getAttendeeCount(); i++)
events[i].displayReservations();
}
Event.java
...
private String ID;
private int attendeeLimit;
private int attendeeCount;
private int placesAvailable;
private Attendee[] a = new Attendee[attendeeCount];
public Demonstration(..., String ID, int placesAvailable, int attendeeLimit, ...) {
this.ID = ID;
this.placesAvailable = placesAvailable;
this.attendeeLimit = attendeeLimit;
}
public String getID() { return this.ID; }
public int getPlacesAvailable() { return this.placesAvailable; }
public int getAttendeeLimit() { return this.attendeeLimit; }
public void setPlacesAvailable(int placesAvailable) { this.placesAvailable = placesAvailable; }
public boolean addAttendee(Attendee at) {
// Proceed to add the attendee if there is enough room.
if (attendeeCount <= placesAvailable) {
attendeeCount++;
// Decrease the number of places available by one.
setPlacesAvailable(placesAvailable - 1);
return true;
}
return false;
}
public void displayReservations() {
System.out.println("ID: " + ID);
if (attendeeCount > 0)
for (int i = 0; i < attendeeCount; i++)
a[i].attendeeDetails();
}
Attendee.java
private String name;
private String phone;
public Attendee(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() { return this.name; }
public String getPhone() { return this.phone; }
public void attendeeDetails() {
System.out.println("Name: " + name);
System.out.println("Phone: " + phone);
}
The above code gives me a ArrayIndexOutOfBoundsException error in the displayReservations() method (a[i].attendeeDetails()) whenever I try to add an attendee to an event.
Problem: How do I display all reservation details for all events? Thank you for your help!
EDIT
The error:
Index 0 out of bounds for length 0.
There are a couple of issues with your code:
You are maintaining an attendeeCount separately than the size of the Attendee[], but in your addAttendee() method, you never actually add the new Attendee to the array
Because Attendee[] is an array, it can't grow larger than the size when first initialized. If you want to use an array, instead of an ArrayList that can grow dynamically, you need to initialize the array to the maximum size: placesAvailable:
So, my recommendation would be to switch from using an array to an ArrayList by importing java.util.Arraylist, changing the declaration of the Attendee[] to an ArrayList, and updating the rest of the Event.java code to use the ArrayList, as well as making sure you add the new Attendee in the addAttendee() method. Finally, you don't need to maintain the attendee count separately, just ask the attendees ArrayList it's current size.
Event.java
...
import java.util.*; //You can import all java.util classes
private String ID;
private int attendeeLimit;
private int placesAvailable;
private List<Attendee> attendees = new ArrayList<>(); //Initialize the attendees ArrayList
public Demonstration(..., String ID, int placesAvailable, int attendeeLimit, ...) {
this.ID = ID;
this.placesAvailable = placesAvailable;
this.attendeeLimit = attendeeLimit;
}
public String getID() { return this.ID; }
public int getPlacesAvailable() { return this.placesAvailable; }
public int getAttendeeLimit() { return this.attendeeLimit; }
public void setPlacesAvailable(int placesAvailable) { this.placesAvailable = placesAvailable; }
public boolean addAttendee(Attendee at) {
// Proceed to add the attendee if there is enough room.
if (attendeeCount <= placesAvailable) {
attendees.add(at); //Make sure you add the new Attendee to the list
// Decrease the number of places available by one.
setPlacesAvailable(placesAvailable - 1);
return true;
}
return false;
}
public void displayReservations() {
System.out.println("ID: " + ID);
int attendeeCount = attendees.size(); //Calculate the number of Attendees
if (attendeeCount > 0)
for (int i = 0; i < attendeeCount; i++)
attendees.get(i).attendeeDetails();
}
attendeCount does not have a value as at the time you creating the Array "a". For what you are trying to achieve, I suggest:
i. Use an Arraylist.
ii. Initialize you array in the constructor to attendeLimit.
If possible, I also suggest you use parameter methods where neccessary.

Java: Why is there a NullPointerException when there is no null? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
This is my first time using this site so hopefully this makes sense. I have my code below and when I execute it its giving me a NullPointerException on line 38 in my Library class,
(the line says if (items[i].getTitle() != null && items[i].getTitle().equals(title)) {)
and another NullPointerException on like 29 in my MainMethod class,
(line is if (loaned == true) {).
To check the contents of items[i], after I added an item I had printed in the console to see if it was null and it successfully printed so I am confused as to why the NullPointerExpcetion is present. Any and all help will be greatly appreciated.
public class MediaItem {
private String title;
private String format;
public boolean onLoan;
public String loanedTo;
public String dateLoaned;
MediaItem() {
onLoan = false;
loanedTo = null;
dateLoaned = null;
title = null;
format = null;
}
MediaItem(String title, String format) {
this.title = title;
this.format = format;
}
public String getTitle() {
return this.title;
}
public String setFormat(String format) {
this.format = format;
return this.format;
}
public String getFormat() {
return format;
}
void markOnLoan(String name, String date) {
if (onLoan == true) {
System.out.println(title + " is already on loan to " + loanedTo);
} else {
onLoan = true;
loanedTo = name;
dateLoaned = date;
}
}
void markReturned() {
}
}
import java.util.Scanner;
public class Library {
int numberOfItems = 0;
MediaItem[] items = new MediaItem[100];
int displayMenu() {
Scanner s = new Scanner(System.in);
System.out.println(
"1. Add an item \n2. Mark an item as on loan \n3. List all items \n4. Mark an item as returned \n5. Quit \n\nWhat would you like to do?");
int choice = s.nextInt();
return choice;
}
void addNewItem(String title, String format) {
items[numberOfItems] = new MediaItem(title, format);
numberOfItems++;
}
void markItemOnLoan(String title, String name, String date) {
for (int i = 0; i <= 100; i++) {
if (items[i].getTitle() == title) {
items[i].onLoan = true;
items[i].loanedTo = name;
items[i].dateLoaned = date;
}
}
}
boolean checkIfLoaned(String title) {
char loaned = 'N';
System.out.println(items[0].getTitle());
for (int i = 0; i < 100; i++) {
if (items[i].getTitle() != null && items[i].getTitle().equals(title)) {
if (items[i].onLoan) {
String personName = items[i].loanedTo;
System.out.println(title + " is already on loan to " + personName);
loaned = 'Y';
}
}
}
if (loaned == 'Y') {
return true;
} else {
return false;
}
}
}
import java.util.Scanner;
public class MainMethod {
public static void main(String[] args) {
int choice = 1;
String personName;
String mediaName;
String format;
String loanDate;
Scanner s = new Scanner(System.in);
Library l = new Library();
while (choice != 5) {
choice = l.displayMenu();
switch (choice) {
case 1:
System.out.println("What is the title?");
mediaName = s.nextLine();
System.out.println("What is the format?");
format = s.nextLine();
l.addNewItem(mediaName, format);
break;
case 2:
System.out.println("Which item (enter the title)?");
mediaName = s.nextLine();
System.out.println("Who are you loaning it to?");
personName = s.nextLine();
boolean loaned = l.checkIfLoaned(mediaName);
if (loaned == true) {
break;
}
System.out.println("When did you loan the item?");
loanDate = s.nextLine();
l.markItemOnLoan(mediaName, personName, loanDate);
}
}
}
}
I am assuming this is homework, so I will steer you in the right direction, as opposed to posting code.
You are iterating through a hard-coded value of 100 items in both markItemOnLoan and checkIfLoaned. Just because you declare an array of 100 items, does not mean they are all initialized. Consider altering your loops to iterate through numberOfItems instead of 100. You should also do a check in addNewItem to ensure you won't surpass 100 items.
Related to #1, you do not check if the actual item you are extracting from the array is null, so you're attempt to call a method getTitle on a null Object, naturally throws a NPE.
Side note, in markItemOnLoan, you're incorrectly comparing Strings. The way you compare titles in checkIfLoaned is correct.
it would be better if you post the callstack too. 3 potential errors I can see are :
items[i] might be null. Although you are checking for null on items[X].getTitle()... You don't perform a null check on items[i]
Your for loop goes from 0 to 100. Is it gauranteed that all elements in array from 0-99 index are populated ? Shouldn't you go from 0 to items.length ?
Your array is defined for 100 elements. You are trying to access 101st elements in the for loop (i<=100) should be i < 100.
Why is there a NullPointerException when there is no null?
It cannot happen.
From this we deduce that there is a null. That is simple logic.
If you are going to succeed in debugging a program MUST NOT deny what the evidence tells you.
So where is the null?
if (items[i].getTitle() != null && items[i].getTitle().equals(title)) {
Based on this line alone there are four possible explanations:
items is null
items[i] is null
another thread is changing something ... and you got unlucky.
the getTitle() method is returning something that is not a String or that is not the same String each time.
We can eliminate the first and fourth explanations by reading the code, and the third one is extremely unlikely (even supposing that it is possible).
That leaves the second explanation as the "working hypothesis".

Need help using an ArrayList

It seems that 20 regiments were in a continuous process of formation. The first had 1000 men, the second had 950, the third 900, and so on down to the twentieth regiment, which garrisoned only 50. During each week, 100 men were added to each regiment, and at week's end, the largest regiment was sent off to the front.This lasted for a total of 20 weeks.
For this program I have already managed to print out the original number of men for each regiment. But I am having difficult adding 100 men to each regiment.The adding men must be a method in the army class. I am getting the regiment objects using a .txt file. All this files contains is the names of regiments numbered 1-20.
I currently have no errors my only problem is that I do not know how to add men to my regiment. I have to use the addMen method in the army class which I currently have blank.
public class Regiment {
private String name; //name of regiment
private int regNumber; //regiment number
private int men; // regiment men
public Regiment(int regNumber, String name, int men) {
this.name = name;
this.regNumber = regNumber;
this.men = men;
}
public String getName() {
return name;
}
public int getregNumber() {
return regNumber;
}
public int getMen() {
return men;
}
public int addMen2(int RegNumber) {
int men = 1050 - (regNumber * 50);
return men;
}
}
ArmyDataList:
class ArmyDataList {
public ArrayList<Regiment> list;
public ArmyDataList() {
list = new ArrayList<Regiment>();
}
public void AddToList(Regiment current) {
list.add(current);
}
public void RemoveFromList(Regiment current) {
list.remove(current);
}
public Regiment getLargest() {
if (list.isEmpty()) {
return null;
}
Regiment Reg1 = list.get(0);
for (int i = 1; i < list.size(); i++) {
Regiment current = list.get(i); // get next regiment
// is current regiment > largest
if (current.getMen() > Reg1.getMen()) {
Reg1 = current;
}
}
return Reg1;
}
public void addMen() {
}
public String toString() {
String out
= String.format("%28s%12s%n", "Regiments", " Men")
+ String.format("%12s%n", "Number")
+ String.format("%12s%16s%14s%n", "=======", "===============",
"=========");
for (int i = 0; i < list.size(); i++) {
Regiment regim = list.get(i);
int regNumber = regim.getregNumber();
String name = regim.getName();
int men = regim.addMen2(regNumber);
out = out + String.format("%12s", regNumber)
+ String.format("%16s", name)
+ String.format("%10s", men)
+ "\n";
}
return out + "\n";
}
}
RegimentTest:
public class RegimentTest {
public static void main(String[] args) throws IOException
{
ArmyDataList army = new ArmyDataList();
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line) ;
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder) ;
}
System.out.println(army.toString());
}
Add a setMen(int numberOfMen) method to your Regiment class. Then in your addMen() method, you can do something like this:
public void addMen(){
for(Regiment r : list){ //iterate through the list of regiments
r.setMen(r.getMen() + 100); //add 100 men to each regiment
}
}
The setMen method would look like this:
public void setMen(int numberOfMen){
men = numberOfMen;
}
There is another issue with your toString method, where the regiment's addMen2 method is called - right now you're just printing the number, not initializing the number of men. In the constructor for your Regiment class, replace the line
this.men = men;
with
this.men = addMen2(regNumber);
Then in your toString method, replace
int men = regim.addMen2(regNumber);
with
int men = regim.getMen();
Here is what your main should look like:
public static void main(String[] args) throws IOException{
ArmyDataList army = new ArmyDataList();
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line);
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder);
}
System.out.println(army.toString()); //print out the initial # of men
for(int i = 0; i < 20; i++)
army.addMen();
System.out.println(army.toString()); //print the final # of men
}
in Regiment get rid of method addMen2, and replace it with
public void addMen(int men) {
this.men +=men;
}
then in your army you could have method
public void addMen(int men) {
for(Regiment regiment : list){
regiment.addMen(men);
}
}
that will be simplest solution to add 100 men to each regiment,
other thing is, your toString is bit nasty, regiment should know how meny soldiers it ghas, you shouldnt need additional method to calculate it (reason why i recommend you to trash addMen2 method)
to initiate your Regiment, use constructor. You want to have regiments in sizes 1000, 1950, 1900 etc, do it when you are creating them
while (fileScan.hasNext()) {
String line = fileScan.nextLine();
System.out.println(line);
Scanner in = new Scanner(line) ;
int regNumber = in.nextInt();
String name = in.next();
int men = 1050 - (regNumber * 50);
Regiment adder = new Regiment(regNumber, name, men );
army.AddToList(adder) ;
}

Logic of deleting in Java

I cant figure out how to start a method to delete a specific entry stored in an array...
I used to do this:
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
}
}
}
but I was advised not to assign the entry[i] to null because it will ruin my entries...
I have no idea how to code it in another way...
What should I need to do is:
I need to delete a specific entry from an array
please help...
also... its output was error it says:
Exception in thread "main" java.lang.NullPointerException
at AddressBook.viewAll(AddressBook.java:62)
at AddressBook.main(AddressBook.java:36)
Java Result: 1
This is my code in my main program:
public class AddressBook {
private AddressBookEntry entry[];
private int counter;
private String SName;
public static void main(String[] args) {
AddressBook a = new AddressBook();
a.entry = new AddressBookEntry[100];
int option = 0;
while (option != 5) {
String content = "Choose an Option\n\n"
+ "[1] Add an Entry\n"
+ "[2] Delete an Entry\n"
+ "[3] Update an Entry\n"
+ "[4] View all Entries\n"
+ "[5] View Specific Entry\n"
+ "[6] Exit";
option = Integer.parseInt(JOptionPane.showInputDialog(content));
switch (option) {
case 1:
a.addEntry();
break;
case 2:
a.deleteEntry();
break;
case 3:
a.editEntry();
break;
case 4:
a.viewAll();
break;
case 5:
a.searchEntry();
break;
case 6:
System.exit(1);
break;
default:
JOptionPane.showMessageDialog(null, "Invalid Choice!");
}
}
}
public void addEntry() {
entry[counter] = new AddressBookEntry();
entry[counter].setName(JOptionPane.showInputDialog("Enter name: "));
entry[counter].setAdd(JOptionPane.showInputDialog("Enter add: "));
entry[counter].setPhoneNo(JOptionPane.showInputDialog("Enter Phone No.: "));
entry[counter].setEmail(JOptionPane.showInputDialog("Enter E-mail: "));
counter++;
}
public void viewAll() {
String addText = " NAME\tADDRESS\tPHONE NO.\tE-MAIL ADD\n\n";
for (int i = 0; i < counter; i++) {
addText = addText + entry[i].getInfo() + "\n";
}
JOptionPane.showMessageDialog(null, new JTextArea(addText));
}
public void searchEntry() {
int notfound = 0;
SName = JOptionPane.showInputDialog("Enter Name to find: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, entry[i].getInfo2());
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
notfound = 0;
}
public void editEntry() {
int notfound = 0;
SName = JOptionPane.showInputDialog("Enter Name to edit: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
entry[i] = new AddressBookEntry();
entry[i].setName(JOptionPane.showInputDialog("Enter new name: "));
entry[i].setAdd(JOptionPane.showInputDialog("Enter new add: "));
entry[i].setPhoneNo(JOptionPane.showInputDialog("Enter new Phone No.: "));
entry[i].setEmail(JOptionPane.showInputDialog("Enter new E-mail: "));
break;
} else {
notfound++;
}
}
if (notfound != 0) {
JOptionPane.showMessageDialog(null, "Name Not Found!");
}
notfound = 0;
}
public void deleteEntry() {
SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int i = 0; i < counter; i++) {
if (entry[i].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[i] = null;
break;
}
}
}
}
Assigning the values to null is going to be the easiest practice. If you're really picky, you could resize the array, but that would be rather pointless. Just keep a separate size counter and decrement it each time you set something to null.
Another reason you're getting a null pointer exception is that you have to consider what's happening when you're replacing values in your array with null but still iterating by counter. You're going to be left with holes in your array upon deletion. The first solution would be to bypass null values altogether, and just shift your array down (somewhat of an expensive operation). The second would be to alter your methods to take those null values into consideration. Example:
public void viewAll() {
String addText = " NAME\tADDRESS\tPHONE NO.\tE-MAIL ADD\n\n";
int nonNull = 0;
for (int i = 0; i < entry.length; i++) {
if (entry[i] != null) {
addText = addText + entry[i].getInfo() + "\n";
nonNull++;
}
if (nonNull == counter) break;
}
JOptionPane.showMessageDialog(null, new JTextArea(addText));
}
I don't have a compiler on this computer, so consider it more of psuedo-code. But the idea is that the counter is only keeping track of how many non-null values you have in your address book, and that these null values could be in random places of your array. I added the nonNull integer as a local counter to keep track of how many values you've encountered that aren't null (so you aren't forced to run through the entire address book). Then, I added the if statement to ensure that the value at entry[i] isn't a null value (trying to invoke getInfo() on a null value is what's giving you that error). Lastly, I added the if statement to break the loop if you've encountered all of the non-null values you have stored. Hope this helps. (Also it may be worth considering a LinkedList to eliminate the null values all together).
Actually, for simplicity's sake, you probably are much better off using a LinkedList, unless you are required to use an array, since you would need to alter all of your methods to take null spaces in your array into account. Assuming you're familiar with LinkedLists of course.
Arrays are immutable. You can change the value for a particular index in the array but you can't change the array size itself. To "delete", you could do:
myArray[index] = null;
And just treat null values as unset/deleted entries.
Assigning to null (currently what you are doing) is the proper thing to do. That will eliminate the reference to the object at that index and allow it to be garbage collected.
Replace entry[i] = null; with this:
System.arraycopy(entry, i + 1, entry, i, counter - i - 1);
--counter;
entry[counter] = null; // optional; helps with garbage collection
--i; // required to not skip the next element
(I'm assuming here that counter is the number of valid entries in entry. This will leave no null entries among the first counter elements of entry (assuming that there weren't any to start with).
Further thought: If you need the array length to always match the number of valid entries, you'll have to re-allocate the array and copy the values over. Just use arraycopy to copy entries from 0 through i-1 and from i+1 to counter-1 into the new array and then assign it to entry. This isn't particularly efficient and is best avoided if possible.
Better to this is List which has remove() method. But if you really want use Array I recommend you change Array to List and then remove all values, after it you can always change List to Array
import javax.swing.JOptionPane;
public class Test {
private static User[] entry = new User[] { new User("Gil"),
new User("Bil"), new User("John") };
public static void main(String... args) {
final Test test = new Test();
test.deleteEntry();
for (int index = 0; index < entry.length; index++) {
User user = entry[index];
if (user != null)
System.out.println(entry[index]);
}
}
public void deleteEntry() {
String SName = JOptionPane.showInputDialog("Enter Name to delete: ");
for (int index = 0; index < entry.length; index++) {
if (entry[index].getName().equals(SName)) {
JOptionPane.showMessageDialog(null, "Found!");
entry[index] = null;
break;
}
}
}
private static class User {
private String name;
public User(String name) {
this.name = name;
}
/**
* #return the name
*/
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
}

Categories