I am dealing with a classical Nim game project. The hurdle for me is to "only" use an array to save player in an object array, which means I will always get NullPointerException when testing. And I've searched almost all the information that there is no such a way to handle this problem.
One way to deal with it is to add if arr[i] != null for checking non-null object when iterating, but then, I need to write it for every method I created. Is there any way to pass only the non-null array to be checked?
Here is part of my code Nimsys:
public static void main(String[] args) {
System.out.println("Welcome to Nim\n");
Scanner in = new Scanner(System.in);
while (true) {
System.out.print('$');
String commandin = in.next();
if (commandin.equals("addplayer")) {
String inputName = in.nextLine();
String[] name = splitName(inputName);
addPlayer(name);
}
if (commandin.equals("removeplayer")) {
String user = in.nextLine().trim();
if (user.equals("")) {
System.out.println("Are you sure you want to remove all players? (y/n) \n");
commandin = in.next();
if (commandin.equals("y")) {
for (int i = 0; i < NimPlayer.getCounter(); i++) {
NimPlayer.getPlayer()[i] = null;
}
System.out.println("Remove all the players");
}
}
if (!user.equals("")) {
searchAndRemovePlayer(user);
}
}
public static void searchAndRemovePlayer(String user) {
for (int i = 0; i < NimPlayer.getCounter(); i++) {
String userName = NimPlayer.getPlayer()[i].getUserName().trim();
if (userName.equals(user)) {
NimPlayer.getPlayer()[i] = null;
System.out.println("Remove successfully!\n");// A test to see if the code runs
return;
}
}
System.out.println("The player does not exist.\n");
}
}
And, below is part of my NimPlayer class.
//username, given name, family name, number of game played, number of games won
public class NimPlayer {
private String userName;
private String familyName;
private String givenName;
private int score;
private int gamePlayed;
private static int counter;
private static final int SIZE = 5;
static NimPlayer[] playerList = new NimPlayer[SIZE]; // set an array here
//define NimPlayer data type
public NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
// create new data using NimPlayer data type
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter<SIZE) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
}
public static int getCounter() {
return counter;
}
public static NimPlayer [] getPlayer() {
return playerList;
}
//getters and setters
}
You can do as below,
public static void searchAndRemovePlayer(String user) {
NimPlayer[] players = Arrays.stream(NimPlayer.getPlayer())
.filter(Objects::nonNull)
.toArray(NimPlayer[]::new);
for (int i = 0; i < players.length; i++) { // replaced NimPlayer.getCounter() to avoid Index Out of Bound
String userName = players[i].getUserName().trim();
if (userName.equals(user)) {
players[i] = null;
System.out.println("Remove successfully!\n");// A test to see if the code runs
return;
}
}
System.out.println("The player does not exist.\n");
}
Note that NimPlayer.getCounter() is replaced with arr length to avoid ArrayIndexOutOfBoundsException
Update:
You can add the logic in getPlayer()
public static NimPlayer [] getPlayer() {
NimPlayer[] nimPlayers = Arrays.stream(playerList)
.filter(Objects::nonNull)
.toArray(NimPlayer[]::new);
counter = nimPlayers.length; //update the counter
return nimPlayers;
}
Try to create a non-null array outside the given section of the program. In the sense, use a loop to create a non-null array that you can use throughout both programs and you can probably store that in a method or instance variable.
Related
I am building a classical Nim game using only the array, and I found there is a bug after testing. If I successfully create a player, I'll assign a new object to the array. However, when removing the player in the array, I filter the array with non-null objects because I have other functions such as editplayer, displayplayer to iterate the entire array without NullPointerException.
And there is a chance that this happens: addplayer → removeplayer → addplayer. It means I'll always get IndexOutOfBound when I try to assign a new object to the array already full of the non-null objects.
I've searched for all the information I could, but there is no such discussion about this. Is there any way to avoid both NullPointerException and IndexOutOfBound at the same time?
Here is related code Nimsys:
public class Nimsys {
public static void addPlayer(String [] name) {
if (name != null && name.length == 3) {
for (int i = 0; i < NimPlayer.getCounter(); i++) {
String userCheck = NimPlayer.getPlayer()[i].getUserName();
if (userCheck.contains(name[0])) {
System.out.println("The player already exists.\n");// Test if player has been created
return;
}
}
NimPlayer.createPlayer(name[0], name[1], name[2]);
System.out.println("The player has been created.");
return;
}
System.out.println("Not Valid! Please enter again!");
}
public static void searchAndRemovePlayer(String user) {
NimPlayer [] playerList = NimPlayer.getPlayer();
for (int i = 0; i < playerList.length; i++) {
String userName =playerList[i].getUserName().trim();
if (userName.equals(user)) {
playerList[i] = null;
System.out.println("Remove successfully!");
NimPlayer.setPlayerList(playerList);
return;
}
}
System.out.println("The player does not exist.\n");
}
}
Here is part of NimPlayer class:
public class NimPlayer {
private String userName;
private String familyName;
private String givenName;
private int score;
private int gamePlayed;
private static int counter;
private static final int SIZE = 10;
private static NimPlayer[] playerList = new NimPlayer[SIZE]; // set an array here
//define NimPlayer data type
public NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
// create new data using NimPlayer data type
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter < SIZE) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
}
public static int getCounter() {
return counter;
}
public static NimPlayer [] getPlayer() {
return playerList;
}
public static void setPlayerList(NimPlayer [] newplayerList) {
playerList = Arrays.stream(newplayerList).filter(Objects::nonNull).toArray(NimPlayer[]::new);
counter = playerList.length; //update the counter
}
//setters and getters of the other variables
}
Instead of explaining about these exceptions, I recommend you go through the documentation of NullPointerException and ArrayIndexOutOfBoundsException. It is not a big deal to handle these exceptions when they occur. However, the most important thing is to prevent them i.e. you should understand what is the root cause and work on them. We all know, "Prevention is better than cure.".
You should always try to hide as much information from the class as is possible e.g. you already have a public static void createPlayer then, why have you created a public constructor? Why have you created a public getter for counter which is meant to be used only internally in the class, NimPlayer?
Instead of exposing the playerList to be set from outside, you should remove its public setter and create public static void removePlayer similar to public static void createPlayer.
On a side note (because it won't affect the execution of the program), the name of an identifier should be self-explanatory e.g. your getPlayer method should be named as getPlayerList as it is returning the playerList, not a single player.
Given below is the code incorporating these comments:
import java.util.Arrays;
import java.util.Objects;
class NimPlayer {
private String userName;
private String familyName;
private String givenName;
private int score;
private int gamePlayed;
private static int counter;
private static final int SIZE = 10;
private static NimPlayer[] playerList = new NimPlayer[SIZE];
private NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter < SIZE) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
}
public static void removePlayer(NimPlayer player) {
int i;
for (i = 0; i < playerList.length; i++) {
if (playerList[i] != null && playerList[i].getUserName().equals(player.getUserName())) {
break;
}
}
for (int j = i; j < playerList.length - 1; j++) {
playerList[j] = playerList[j + 1];
}
counter--;
}
public static NimPlayer[] getPlayerList() {
return Arrays.stream(playerList).filter(Objects::nonNull).toArray(NimPlayer[]::new);
}
public String getUserName() {
return userName;
}
public String getFamilyName() {
return familyName;
}
public String getGivenName() {
return givenName;
}
#Override
public String toString() {
return userName + " " + familyName + " " + givenName;
}
}
class NimSys {
public static void addPlayer(String[] name) {
if (name != null && name.length == 3) {
NimPlayer[] playerList = NimPlayer.getPlayerList();
for (int i = 0; i < playerList.length; i++) {
String userCheck = playerList[i].getUserName();
if (userCheck.contains(name[0])) {
System.out.println("The player, " + name[0] + " already exists.\n");
return;
}
}
NimPlayer.createPlayer(name[0], name[1], name[2]);
System.out.println("The player, " + name[0] + " has been created.");
return;
}
System.out.println("Not Valid! Please enter again!");
}
public static void searchAndRemovePlayer(String user) {
NimPlayer[] playerList = NimPlayer.getPlayerList();
for (int i = 0; i < playerList.length; i++) {
String userName = playerList[i].getUserName().trim();
if (userName.equals(user)) {
NimPlayer.removePlayer(playerList[i]);
System.out.println("The player, " + user + " removed successfully!");
return;
}
}
System.out.println("The player, " + user + " does not exist.\n");
}
public static void displayPlayerList() {
NimPlayer[] playerList = NimPlayer.getPlayerList();
StringBuilder sb = new StringBuilder();
for (NimPlayer player : playerList) {
sb.append(player.getUserName()).append(" ").append(player.getFamilyName()).append(" ")
.append(player.getGivenName()).append(System.lineSeparator());
}
System.out.println(sb);
}
}
public class Main {
public static void main(String[] args) {
NimSys.addPlayer(new String[] { "Harry", "Potter", "Harry" });
NimSys.displayPlayerList();
NimSys.searchAndRemovePlayer("Harry");
NimSys.displayPlayerList();
NimSys.addPlayer(new String[] { "Manny", "Richard", "Canty" });
NimSys.displayPlayerList();
NimSys.addPlayer(new String[] { "Arvind", "Kumar", "Avinash" });
NimSys.displayPlayerList();
NimSys.searchAndRemovePlayer("Manny");
NimSys.displayPlayerList();
NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
NimSys.displayPlayerList();
NimSys.searchAndRemovePlayer("Ken");
NimSys.displayPlayerList();
NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
NimSys.displayPlayerList();
NimSys.searchAndRemovePlayer("Ken");
NimSys.displayPlayerList();
NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
NimSys.displayPlayerList();
}
}
Output:
The player, Harry has been created.
Harry Potter Harry
The player, Harry removed successfully!
The player, Manny has been created.
Manny Richard Canty
The player, Arvind has been created.
Manny Richard Canty
Arvind Kumar Avinash
The player, Manny removed successfully!
Arvind Kumar Avinash
The player, Ken has been created.
Arvind Kumar Avinash
Ken Ken Thompson
The player, Ken removed successfully!
Arvind Kumar Avinash
The player, Ken has been created.
Arvind Kumar Avinash
Ken Ken Thompson
The player, Ken removed successfully!
Arvind Kumar Avinash
The player, Ken has been created.
Arvind Kumar Avinash
Ken Ken Thompson
To answer your question: "Is there any way to avoid both NullPointerException and IndexOutOfBound at the same time?"
Yes, you can do that by using the following two things.
First, you can get the length of the array using its length property. length is the number of elements in the array (including those whose value is null). With that information you should never be indexing out of bounds (as long as you're not writing concurrent code that modifies the array's length).
Secondly, you need to check what you take out of the array to see if it is null. You can just do that with an if statement.
Here's what that would look like:
// create an array with 5 elements. 0, 2, and 4 are null. 1 and 3 are not null.
String[] myArray = new String[5];
myArray[1] = "abc ";
myArray[3] = "def";
// myArray.length will be '5'
for (int i = 0; i < myArray.length; i++){
String value = myArray[i];
if (value != null) {
// prints "ABC DEF" and doesn't result in a NullPointer
System.out.print(value.toUpperCase());
}
}
So in your case:
public static void addPlayer(String [] name) {
if (name != null && name.length == 3) {
for (int i = 0; i < NimPlayer.getPlayer().length; i++) {
NimPlayer player = NimPlayer.getPlayer()[i];
if (player != null && player.getUserName().contains(name[0]))
System.out.println("The player already exists.\n");
return;
}
}
NimPlayer.createPlayer(name[0], name[1], name[2]);
System.out.println("The player has been created.");
return;
}
System.out.println("Not Valid! Please enter again!");
}
And just to add. In object oriented programming you generally want to follow the principle of encapsulation - so you probably want to move the methods in NimSys into NimPlayer since they operate on the data in NimPlayer.
I'm guessing you're new to Java and programming. Good luck learning!
public class studentDriver {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("How many students are there?: ");
int numberOfstuds = scan.nextInt();
int[] nOEarray = new int[numberOfstuds];
System.out.println("\nEnter names of students up to the entered amount (" + numberOfstuds + "):");
String[] namesArray = new String[numberOfstuds];
for (int i = 0; i < numberOfstuds; i++) {
namesArray[i] = scan.next();
}
System.out.println(Arrays.toString(namesArray));
}
}
That is part of my code for letting user input array size, however I am tasked with using the header below just for a method to get the size of the array, but I have tried inserting it and keep getting different error messages such as needs body(if I put semi-colon) or "requires ';'" if I don't and when I put curly braces around the section where it gets the array size it returns errors :Syntax error, insert "[ ]" to complete Dimension
- Syntax error, insert ";" to complete BlockStatements
- Syntax error on token "create", AnnotationName expected after
this token
public static Student[] create()
Here is the Student class
public class Student {
//private data members
private String name;
private long idNUmber;
//constructor
public Student(){
name="Unassigned";
idNUmber=0;
}
//overloaded constructor
public Student(String x, long y) {
name=x;
idNUmber=y;
}
//getters
public String getName() {
return name;
}
public long getIdNUmber() {
return idNUmber;
}
//setters
public void setName(String n) {
name=n;
}
public void setIdNUmber(long i) {
idNUmber=i;
}
//override
public String toString() {
return "Name: "+getName()+"\nID number: "+getIdNUmber();
}
Below is my code and I have notes beside where my errors are showing. Im unsure where I am going wrong when recalling my method or if that is even the issue.
import java.util.Scanner;
public class HurlerUse
{
static Hurler[] hurlerArray;
// find lowest score (static method)
public static int findLow(Hurler[] hurlerArray)
{
for(int i = 0; i < hurlerArray.length; i++)
{
int lowest = 0;
int index = 0;
for(int j=0; j<hurlerArray.length; j++)
{
int current = hurlerArray[i].totalPoints();// issue with my method 'totalPoints'
if(current < lowest)
{
lowest = current;
index = i;
}
}
return index;
}
}
//main code
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
Hurler[] hurlerArray = new Hurler[5];
for (int i = 0; i <4; i++)
{
hurlerArray[i] = new Hurler();
System.out.println ("Enter Hurler Name:");
hurlerArray[i].setName(sc.nextLine());
hurlerArray[i].setGoalsScored(sc.nextInt());
System.out.println("Enter the hurler's goals scored");
hurlerArray[i].setPointsScored(sc.nextInt());
System.out.println("Enter the hurler's points scored");
}
for(int i=0;i< hurlerArray.length; i++)
{
hurlerArray[i] = new Hurler(MyName, MyGoalsScored, MyPointsScored);// issue with all 3 objects in the brackets but im unsure of how to fix them
}
System.out.println("The lowest scoring hurler was " + hurlerArray[findLow(hurlerArray)].getName());// error with my code here I think it is in the method
}
}//end of class
I know the nyName, myGoalsScored, myPointsScored is incorrect but can anyone explain why?
This is the class page that accompanies it
public class Hurler
{
private String name;
private int goalsScored;
private int pointsScored;
public Hurler() //constructor default
{
name ="";
goalsScored = 0;
pointsScored = 0;
}
public Hurler(String myName, int myGoalsScored, int myPointsScored) // specific constructor
{
name = myName;
goalsScored = myGoalsScored;
pointsScored = myPointsScored;
}
//get and set name
public String getMyName()
{
return name;
}
public void setName(String myName)
{
name = myName;
}
//get and set goals scored
public int getGoalsScored()
{
return goalsScored;
}
public void setGoalsScored(int myGoalsScored)
{
goalsScored = myGoalsScored;
}
// get and set points scored
public int getPointsScored()
{
return pointsScored;
}
public void setPointsScored(int myPointsScored)
{
pointsScored = myPointsScored;
}
public int totalPoints(int myGoalsScored, int myPointsScored)
{
int oneGoal = 3;
int onePoint = 1;
int totalPoints = ((goalsScored * oneGoal) + (pointsScored * onePoint));
{
return totalPoints;
}
}
}//end of class
You call totalPoints() without parameters while method totalPoints(int, int) in Hurler class expects two int parameters.
Objects MyName, MyGoalsScored, MyPointsScored are not declared at all.
You call getName() method, while in Hurler class you do not have one. There is method getMyName(), maybe you want to call that one.
I am working on an assignment and I can not figure out what to do. I have three different Java classes. And I am trying to use the methods in one class to do something in a different class. I am making a very primitive playlist program. I have to check to see if the playlist is full, if its not i have to ask the title and artist. Then I have to call my method using the title and artist as parameters. I was wondering if anyone could point me in the right direction as to what I had to do to call the method? I still don't completely understand loops either but i know that I have to use a for loop in order to do this. Thankyou for your time.
Here is my code:
Main Class
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
PlayList p = new PlayList (5);
Scanner sc = new Scanner(System.in);
String command;
String title;
String artist;
System.out.println("Enter a to add, r to remove, d to display,or q to
quit:");
command = sc.nextLine();
while (!command.equals("q")) {
// Interpret command
if (command.equals("a")) {
//add song
for (int i = 0; i <= PlayList.isFull(title, artist);i++) {
if(songs[i])== null {
songs[i] = filled;
}
}
} else if (command.equals("r")) {
// Remove a song
System.out.print("Title: ");
title = sc.nextLine();
p.remove(title);
} else if (command.equals("d")) {
// Fill this in
}
// Get the next command
System.out.println("Enter a to add, r to remove, d to display, or q to
quit:");
command = sc.nextLine();
}
System.out.println("Program Ended");
}
}
PlayList Class
public class PlayList {
private Song [] songs;
private int filled;
public PlayList (int size){
songs = new Song[size];
}
public boolean isFull() {
return (filled >= songs.length);
}
public void add(String t, String a) {
for (int i = 0; i < songs.length; i++){
if (songs[i] == null){
songs[i] = new Song(t,a);
filled++;
}
}
}
public void display() {
for (int i = 0; i < songs.length; i++){
if (songs[i] != null) {
System.out.println(songs[i]);
}
}
}
public void remove(String t) {
//return t?
for (int i = 0; i < songs.length; i--){
if (songs[i] == null){
songs[i] = null;
break;
}
}
}
}
Song Class
public class Song {
String title;
String artist;
public Song (String t, String a) {
title = t;
artist = a;
}
public String toString() {
return "Title: " + title + " " + "Artist: " + artist;
}
}
First of all you are using isFull function of class PlayList wrong.
for (int i = 0; i <= PlayList.isFull(title, artist);i++)
isFull is a no argument function, and you are using it with passing 2 arguments.
isFull function returns a boolean value (i.e. true/false), but you are comparing it with an int, which does not make any sense.
isFull is not a static function. Therefore you cannot use it directly with class name.
-either you will need to declare function isFull as static.
public static boolean isFull()
-or you will need to create an object of class PlayList in class Main and then call the java function using that java object.
Also, your Function remove is not performing any task
if (songs[i] == null){
songs[i] = null;
}
It is checking if songs[i] is already null and then it sets it back to null, which does not make any sense.
And you should increment i (i.e. i++) not decrement it (i.e. i--)
for (int i = 0; i < songs.length; i--)
If you want to call method from another class that method must be a static method. Then you can call it using Class name and Method name.
For an example;
public class main(){
A a = new A();
a.x();
}
public class A{
public static void x(){};
}
You called isFull method with two parameters but your PlayList class does not have any parameter for isFull method. That is an error.
I re-write your assignment class set using ArrayList for PlayList class. Follow this codes. Hope you can understand it's concept of OOP(Follow this tutorials. https://www.javatpoint.com/java-oops-concepts).
Main Class
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
PlayList p = new PlayList (5);
Scanner sc = new Scanner(System.in);
String command;
String title;
String artist;
System.out.println("Enter a to add, r to remove, d to display,or q to quit:");
command = sc.nextLine();
while (!command.equals("q")) {
// Interpret command
if (command.equals("a")) {
//add song
System.out.println("Enter Title:");
title = sc.nextLine();
System.out.println("Enter Artist:");
artist = sc.nextLine();
if(!p.isFull()) {
p.add(title, artist);
System.out.println("Added Success!");
}
else
System.out.println("Sorry,Playlist is full");
} else if (command.equals("r")) {
// Remove a song
System.out.print("Title: ");
title = sc.nextLine();
p.remove(title);
} else if (command.equals("d")) {
// Fill this in
p.display();
}
// Get the next command
System.out.println("Enter a to add, r to remove, d to display, or q to quit:");
command = sc.nextLine();
}
System.out.println("Program Ended");
}
}
PlayList Class
import java.util.ArrayList;
import java.util.List;
public class PlayList {
private static List<Song> songs;
private static int filled;
private static int size = 0;
public PlayList (int s){
songs = new ArrayList<>();
size = s;
}
public static boolean isFull() {
return (filled == size);
}
public static void add(String t, String a) {
songs.add(new Song(t,a));
filled++;
}
public void display() {
for (int i = 0; i < songs.size(); i++){
if (songs.get(i) != null) {
System.out.println(songs.get(i));
}
}
}
public void remove(String t) {
//return t?
for (int i = 0; i < songs.size(); i++){
if (songs.get(i).title == t){
songs.remove(i);
break;
}
}
}
public static int getSize(){
return songs.size();
}
}
Song Class is same as you wrote.
this is the first class
this is the template class
public class Email{
private String title;
private String to;
private double size;
private boolean sent;
static int numEmails;
public Email(String Title, String To, double Size){
title = Title;
to = To;
size = Size;
numEmails++;
}
public void displayEmail(){
System.out.printf("Subject: %30s%n", title);
System.out.printf("To: %-35s%n",to);
System.out.printf("This email has size: %.2f kB%n",size );
if(sent)
System.out.printf("This email has been sent%n");
else
System.out.printf("This email has not been sent%n");
}
public void sendEmail(){
sent = true;
displayEmail();
}
public boolean isValid(){
int sep = to.indexOf('#');
if(to.substring(sep).equals("#student.ksu.edu.sa"))
return true;
return false;
}
//setters
public void setTitle(String Title){
title = Title;
}
public void setTo(String To){
to = To;
}
public void setSize(double Size){
size = Size;
}
public void setSent(boolean Sent){
sent = Sent;
}
//getters
public String getTitle(){
return title;
}
public String getTo(){
return to;
}
public double getSize(){
return size;
}
public boolean getSent(){
return sent;
}
}//End of class
this is the second class
when I run this it says error StringIndexOutOfBounds
I guess it has to do with the method isValid()
I want to fill the first and second objects in the array by reading from user but there's an error as well which I can't seem to know why when I read from the user
import java.util.*;
public class Inbox{
static Scanner read = new Scanner (System.in);
static Email[] sentEmails = new Email[Email.numEmails];
//archive method
public static Email[] archive(Email[] emailList){
for(int i=0;i<Email.numEmails;i++)
if(emailList[i].getSent())
sentEmails[i] = new Email(emailList[i].getTitle(),emailList[i].getTo(),emailList[i].getSize());
return sentEmails;
}
//findByRecipient method
public static void findByRecipient(Email emailList[], String toAddress){
System.out.println("The emails addressed to \"everyONE#student.ksu.edu.sa\" are:");
System.out.println("==========================");
toAddress = toAddress.toLowerCase();
for(int i=0;i<Email.numEmails;i++)
if(emailList[i].getTo().equals(toAddress))
emailList[i].displayEmail();
}
//main
public static void main(String[] args){
Email[] array = new Email[10];
for(int i=0;i<2;i++){
System.out.printf("Please enter the title, recipient, and size of email %d %n", (Email.numEmails+1));
array[i] = new Email(read.nextLine(),read.nextLine(),read.nextDouble());
;}
array[2] = new Email("Urgent: Lab final","everyone#student.ksu.edu.sa",200);
array[3] = new Email("Fwd: Boarding pass","SaadAli#ksu.edu.sa",100);
array[4] = new Email("You won 1M SR!","email#spam.com",5000.0);
//1
System.out.println("The Inbox currently contains");
System.out.println("==========================");
for(int j=0;j<Email.numEmails;j++){
if(array[j]!=null)
array[j].displayEmail();}
for(int k=0;k<Email.numEmails;k++){
if(array[k].isValid())
array[k].sendEmail();
else
System.out.println("Email is invalid");
}
//2
archive(array);
System.out.println("The Inbox after sending contains:");
System.out.println("==========================");
for(int s=0;s<sentEmails.length;s++){
if(sentEmails[s]!=null)
sentEmails[s].displayEmail();}
//3
findByRecipient(array,"everyONE#student.ksu.edu.sa");
//4
System.out.println("The titles of emails in archive are:");
System.out.println("==========================");
for(int r=0;r<Email.numEmails;r++)
System.out.println(array[r].getTitle());
//5
System.out.println("Number of emails: " + Email.numEmails);
}//End of main
}//End of class
Without seeing the inputs, it's hard to be certain, but your isValid() function doesn't check if the '#' sign exists. If this function is called and the var to doesn't have an '#' sign, var sep will be set to -1, causing an error with the line "to.substring(-1)".