java null manual exception handling - java

I have this static method of the class Plane which returns an object from some int id:
private static ArrayList<Plane>Planes = new ArrayList<Plane>();
public static Plane getPlane(int id)
{
Plane p = null;
int i=0;
while(i<=Planes.size())
{
if(Planes.get(i).getid()==id)
{
p = Planes.get(i);
break;
}
i++;
}`
return p;
}
And I have this code which I want to manually throw an exception when the Plane object is null and print Plane doesnt exist!:
try
{
Plane planetofly = Plane.getPlane(pid);
if(planetofly==null)
{
throw new Exception("Plane doesnt exist!");
}
this.planetofly = planetofly;
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
but instead of getting "Plane doesnt exist at the output" when the plane with that id doesnt exist i get output the message from the IndexOutofBounds Exception.What am I doing wrong?

Index out of bounds means that you are trying to access an index in your array which does not exist.
This line is the problem.
while(i<=Planes.size())
The index starts at zero and ends at Size - 1, so you have to check for less than, not less than or equal to. Like this:
while(i < Planes.size())

Related

I'm trying to give the value of an array of a class to another array with the same class, is there something I'm missing here?

The class is called Exposicion and has a String and an INT value, so I used it as an array to grab some input from the user.
class Exposicion {
public String nombreExpo;
public int duracionExpo;
Exposicion(String nombreExpo, int duracionExpo) {
this.nombreExpo = nombreExpo;
this.duracionExpo = duracionExpo;
}
}
With the Function SortExpo I plan to copy only the values of the array as long as the INT values don't add up to 180, but java flags an error when doing:
arrExpoT[posHor].nombreExpo = arrExpoS[k].nombreExpo;
This is the whole function
void SortExpo(Exposicion[] arrExpoS,int posicion,Exposicion[] arrExpoT){
int poshor=0;
int total=0;
for (int k = 0; k < posicion; k++) {
if ( total < 180 || arrExpoS[poshor].nombreExpo != "TOMADO123") {
arrExpoT[poshor].nombreExpo = arrExpoS[k].nombreExpo;
arrExpoT[poshor].duracionExpo = arrExpoS[k].duracionExpo;
arrExpoS[poshor].nombreExpo = "TOMADO123";
total = total + arrExpoS[k].duracionExpo;
poshor++;
} else {
k = posicion;
}
}
}
Error
I've added the .java file in this link
Also Main.java if this helps
You are getting a NullPointerException because "expo1" and "sala1" variables are both null. You have to pass a reference to an object on both variables. Something like this:
class SalaExpo(){
Exposicion[] expo1=new Exposicion[100];
}
public class ConsoleMenu {
private SalaExpo sala1;
void execute(){
sala1 = new SalaExpo();
}
}
Also you should poblate the sala1.expo1 array, like this (don't know if this is what you are intending but you should do this in order not to get a NullPointerException) :
void GuardarExpo(Exposicion[] arrExpoG,int posicion,Exposicion[] arrSala) {
/*
Bunch
of
code
*/
arrExpoG[posicion] = new Exposicion(inputNombre,inputDuracion);
arrSala[posicion]=arrExpoG[posicion];
}
Finally, you should use the variable "posicion" instead of "sala1.expo1.length" to pass as argument to the "imprimirExpo" method, since the array "sala1.expo1" has a length of 100, that means a lot of null elements since you are not poblating it all:
ImprimirExpo(sala1.expo1,posicion);
instead of:
ImprimirExpo(sala1.expo1,sala1.expo1.length);

Returning a different type than the parameter

This is hw and I am really stuck on how to get my code to return what I want it to return. I am trying to return a String value with a given index value. I thought all I had to do was return the string value at the given index but I am not getting the right answer.
public void add(String candidate){
if (candidate.equals(null)){
throw new RuntimeException();
}
String[] contenders = new String[candidates.length+1];
// copy the array manually because I'm restricted from ArrayLists
for (int i = 0; i < candidates.length; i++){
contenders[i] = this.candidates[i];
}
this.candidate = candidate;
contenders[contenders.length-1] = this.candidate;
this.candidates = new String [contenders.length];
After adding values to a newly constructed array the tester wants to get the string value at a given index
public String get(int index){
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
I have been working on it and I finally was able to have candidate stop pointing to null it is giving the wrong value for the given index so for example I want 'X' at candidate[3] but I am getting 'Y' because that is the last value that candidate keeps. I have tried just returning candidates[index] but then it tells me that the value at that index is null. As I have gone through the debugger it appears that my original array is not being copied over properly but I am not sure what I should try next. Thanks in advance.
This is my constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
this.candidates = new String[candidates.length];
CandidateList candidateList = new CandidateList();
There is a lot that can be improved in your code, let me add some comments
public void add(String candidate){
//if candidate is actually null you are calling null.equals
//which means this will always result in a NullPointerException
//you can remove this if if you want
if (candidate.equals(null)){
throw new RuntimeException();
}
...
//think about what you are doing here,
//you are setting this.candidates to a new empty array
//(is big contenders.length, but still empty)
this.candidates = new String [contenders.length];
Second part:
public String get(int index){
//you are missing an '=' in index >= candidates.length
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
//this for loop is wrong, you are changing 'i' but never use it..
//just return candidates[index] like you said before.
//It was probably null because of the error above
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
A note on the RuntimeException(RE): if you catch a NullPointerException (NPE) and throw a RE you are actually losing information (since NPE is a more specific error rather than RE). If you want to catch/throw put at least a significant message like "candidate cannot be null"
Let's now analyze the constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
// you are doing the same error as above here:
// when you do this you create an EMPTY list of size candidates.lenght
// correct code is this.candidates = candidates
this.candidates = new String[candidates.length];
// this is not necessary, constructors don't need to return anything,
//here you are just creating a new instance that will not be used anywhere
CandidateList candidateList = new CandidateList();
Constructors create objects, they don't return data. I suggest you to take a look at this question Does a Java constructor return the Object reference? and in general read a bit more about constructors

Insert Method in a BinarySearchTree

Hey i have written some kind of Binary Search Tree, which has a insert method.
So it gets a Object to insert, a Char Array and a Integer which gives it the Index to look at.
So this is the insert method :
public void insert(Buchstabe pBuchstabe,char[] pChar,int pStelle)
{
if(pBuchstabe==null)
return;
if(baum.isEmpty())
{
baum=new BinaryTree(pBuchstabe);
}
else
if(pStelle <= pChar.length)
{
if(pChar[pStelle] == '.')
{
Mybaum lTree=this.getLeftTree();
lTree.insert(pBuchstabe,pChar,pStelle+1);
this.baum.setLeftTree(lTree.baum);
}
else
if(pChar[pStelle]=='-')
{
Mybaum lTree=this.getRightTree();
lTree.insert(pBuchstabe,pChar,pStelle+1);
this.baum.setLeftTree(lTree.baum);
}
}
}
I have a Method which passes the required Parameters (in this case) : A Object Buchstabe,then the Char Array['.','.'] and the integer 0 to the insert method.
And i get a out of bounds error :
java.lang.ArrayIndexOutOfBoundsException: 2
at Mybaum.insert(Mybaum.java:22)
at Mybaum.insert(Mybaum.java:25)
at Mybaum.insert(Mybaum.java:25)
at Mörserbaum.einlesen(Mörserbaum.java:42)
Does anyone know what ive made wrong ?
Looks like you have an issue
if(baum.isEmpty())
{
baum=new BinaryTree(pBuchstabe);
}
else
**if(pStelle <= pChar.length)**
{
**if(pChar[pStelle] == '.')**
{
Mybaum lTree=this.getLeftTree();
lTree.insert(pBuchstabe,pChar,pStelle+1);
this.baum.setLeftTree(lTree.baum);
}
if(pChar[pStelle] == '.') -- you get indexOutOfBound bc/ you need to say
if(pChar[pStelle-1] == '.') .. since Java array index starts from 0, if the length is 5, last index would be pChar[4]...
there could be more issues with this code, since we don't have full code/context i can't speculate more.. but this is one of the reason you could get indexoutofbound
public void einlesen()
{
Buchstabeenschlange sch = new Buchstabeenschlange();
for(int i = 0;i<codeTabelle.length;i++)
{
Buchstabe a = new Buchstabe(alphabet[i],codeTabelle[i]);
if(a == null)
{
System.out.println("Buchstabe mit Error == "+a);
}
System.out.println("Buchstabe == "+a);
sch.hinzufuegen(a);
System.out.println("------------");
}
List l = sch.gibListe();
sch.druckeListe();
l.toFirst();
while(l.hasAccess())
{
Buchstabe buch = (Buchstabe) l.getObject();
char[] code = buch.getCode().toCharArray();
baum.insert(buch,code,0);
l.next();
}
TreeViewGUI view = new TreeViewGUI(baum);
}
This creates the object Buchstabe and sorts it in a List so that you have the shortest Strings at the beginning.
Then it inserts them into a Binaray Tree and displays it.

How to return a value from one class to another ? Java

i'm having a bit of a problem. Here's the situation. I have an amount field in my main class that gets incremented when certain buttons are clicked on. There is a method provided through which you can delete any order (I'm basically programming for a restaurant terminal) and the amount gets decremented. The delete method is placed in another class.
public void posdel(int pos, JTextField amountFieldGot, int amountGot)
{
if(slist==null)
{
JOptionPane.showMessageDialog(null, "No order has been placed yet.",null,JOptionPane.WARNING_MESSAGE);
}
else
{
if(pos==1)
{
reductionAmount = (slist.quantity*slist.price);
amountGot = amountGot - reductionAmount;
slist=slist.next;
}
else
{
int i=1;
Node temp=slist;
Node prev=null;
while(temp.next!=null && i<pos)
{
prev=temp;
temp=temp.next;
i++;
}
if(pos==i)
{
prev.next=temp.next;
}
else
{
JOptionPane.showMessageDialog(null, "Invalid order", null, JOptionPane.ERROR_MESSAGE);
}
}
}
amountFieldGot.setText(Integer.toString(amountGot));
}
So basically, I have an amountField in my GUI that i pass as a parameter to the posdel method. I also pass the amount value as a parameter. The new amount that i get is amountGot after the deletion of the first order. ( I haven't written the code for other positions.)
Suppose the amount value i pass into the method is 30 (14+16) 14 = order 1, 16 = order2.
And my first order has a value of 14.
So amountGot = 30 - 14 which is 16.
And the amountField in the GUI gets updated to 16.
Now my order 2 becomes my order 1. And if i try to delete this,
my amountField gets update to 14. (30-16 = 14).
So i'm guessing the amount value stays the same itself as 30 and does not get updated to the new amountGot value. Can someone please help me solve this problem ?
below is the code for my delete button.
deleteButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
dishDelPos = JOptionPane.showInputDialog("Enter the position of the order to be deleted");
try
{
dishDeletePosition = Integer.parseInt(dishDelPos);
order1.posdel(dishDeletePosition, amountField, amount);
repaint();
}
catch(NumberFormatException ex1)
{
JOptionPane.showMessageDialog(null,"This is not a valid position");
}
}
});
A few things.
You can make the delete method in the class static. The you would reference it
value = MyClass.deleteMethod();
You can create a new class to perform the method
MyClass myClass = new MyClass();
value = myClass.deleteMethod();
You can do it using a pointer of sorts, by passing in a reference to an already existing instance of the class holding the delete method, to where you want to call it.
myFunction(MyClass myClass)
{
value = myClass.deleteMethod();
}
basically set up your function to return a value
public static int deleteMethod()
{
}
this function returns an int.
or if you need to return more than that then set the class up with global variables of information
class MyClass
{
public int value1;
public int value2;
public String value3;
public void deleteMethod()
{
//does something with global variables
}
}
now fetch the info after calling delete like so
Myclass myClass = new MyClass();
myClass.deleteMethod();
value1 = myClass.value1
value2 = myClass.Value2
value3 = myClass.Value3

Java: index in array exists, ArrayIndexOutOfBoundsException: 0

Sorry if this is answered somewhere due to me missing something obvious, but I've been googling this for days now and it just doesn't seem to make any sense. I've got 3 years of experience in Javascript and am getting into Java now, so I'm not behind on the basic concepts of anything and such.
I'm using IntelliJ for this, but it fails to point out the problem. The communication (access rights and instantiations) between my classes is fine, the code syntax and variable types are as well, etc, so I really can't tell what it is.
I have a Data class, which just holds "read-only" data for the other classes to use.
public class Data {
// snip
public static int[][] specs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
There's another class that has to read this data when it's initialized.
public class Soldier {
// snip
public int range;
public Soldier() {
int x = ...; // user input
range = Data.specs[x][1];
}
}
The specs array itself contains its data as defined (ie the array is not empty), x is valid as an index of the specs array (ie 0 <= x <= 3), its type is int and Test has read access to the specs array (all confirmed with debug output statements). And yet, when it tries to set the value of range (then and only then, at that exact point), I get the "Index out of bounds" error.
Can someone please tell me what's going wrong when trying to read the array? Or am I right in saying that this is really weird and I need to post the entire code?
Note: a small new test also shows that, if I change the code to first output a manually chosen value from the array and then set the value of range, the console prints the error statement (and exits the program) and follows it up by printing the manually picked value, but assigning the value and then asking to output range only throws the error... That makes absolutely no sense at all!
Edit: I've edited the code above. The class called Test is called Soldier in my code (I'm making a text-based game...). Below's the stack trace, if it's any good without the full code (which is way long). The basic structure of my program is this:
1) Boot contains the main method and instantiates a new Game
2) Game instantiates x Teams
3) each Team instantiates an Army
4) each Army instantiates x Soldiers
Each instance of the classes is set as an attribute of the instantiating class (public Army army; and an Army instantiation in the Team constructor, for example). It's essentially a cascade of constructors instantiating subsequent classes and assigning them as their attributes.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Army.<init>(Army.java:13)
at Team.<init>(Team.java:19)
at Game.<init>(Game.java:22)
at Boot.main(Boot.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)5
Edit edit: here's the semi-full code (I'm leaving out the stuff that has absolutely nothing to do with it, including the imports). It's in no particular order and the classes are in separate .java files within the IntelliJ project. The game continues up to the point where a new Soldier asks for its type to be designated (the function performing the user input is working fine and validating the input as proven by a technically identical other part of the game).
public class Boot {
public static void main(String[] args) {
Object[] games = new Object[] {};
if (Lib.userConfirmPrompt("Start the game?") == true) {
do {
games[games.length] = new Game();
}
while (Lib.userConfirmPrompt("Do you want to play again?") == true);
}
System.exit(0);
}
}
public class Game {
public Object[] teams = new Object[] {};
public Game() {
for (int i = 0;i < settings.xbots + 1;i++) {
teams[teams.length] = new Team(this);
}
}
}
public class Team {
public Game game;
public Army army;
public Team(Game p) {
game = p;
army = new Army(this);
}
}
public class Army {
public Team team;
public static Object[] soldiers = new Object[] {};
public Army(Team p) {
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers[soldiers.length] = new Soldier(this);
}
}
}
public class Soldier {
private Army army;
public int sight;
public int range;
public int distance;
public int damage;
public Soldier(Army p) {
army = p;
int type = Lib.userTxtIntOptionsPrompt(Data.isoldiertypes);
// HERE is where it crashes, type is assigned and valid but the array access fails
sight = Data.isoldierspecs[type][0];
range = Data.isoldierspecs[type][1];
distance = Data.isoldierspecs[type][2];
damage = Data.isoldierspecs[type][3];
}
}
public class Data {
public static List isoldiertypes = Arrays.asList("Scout","Private","Machinegunner","Grenadier");
public static int[][] isoldierspecs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
public class Lib {
private static Scanner input = new Scanner(System.in);
// output
// default: 1 query string to print
public static void outBase(String query) {
System.out.print(query);
}
public static void outStd(String query) {
outBase(query + "\n");
}
// end of output
// input
// default: 1 query string to print,
// query and input are in-line (exception: userConfirmPrompt prints query block-wise and default instruction in-line before input),
// keeps user hostage until valid input is given (exception: userPrompt returns blindly)
public static String userPrompt(String query) {
outBase(query);
return input.nextLine();
}
public static String userTxtPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userPrompt(query);
} while (menuinput.length() == 0);
return menuinput;
}
public static int userIntPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userTxtPrompt(query);
} while(menuinput.matches("^-?\\d+$") == false);
return new Integer(menuinput);
}
// end of input
// options input
// default: takes a List of options as argument,
// prints an enumerated list of these options string-wise,
// prompts for a numeral selection of the desired option and returns the number if valid
public static int userTxtIntOptionsPrompt(List options) {
int choice = 0;
Boolean chosen = false;
do {
if (chosen == true) {
userHostage();
} else {
chosen = true;
}
chosen = true;
for (int i = 0;i < options.size() - 2;i++) {
outStd((i + 1) + ") " + options.get(i) + ",");
}
outStd((options.size() - 1) + ") " + options.get(options.size() - 2) + "\nand " + options.size() + ") " + options.get(options.size() - 1) + ".");
choice = userIntPrompt("Enter the number of the option you'd like to select: ") - 1;
} while(choice < 0 || choice >= options.size());
return choice;
}
// end of options input
// miscellaneous
public static void userHostage() {
outStd("Invalid operation. Please try again.");
}
}
The problem is in your Army class:
public static Object[] soldiers = new Object[] {};
You initialize an empty (length == 0) array named soldiers, but later you access:
soldiers[soldiers.length] = new Soldier(this);
This causes the failure.
By definition, soldiers.length is out of the bound of the array (since the bound is from 0 to soldiers.length-1)
To overcome it - make sure you allocate enough space in the array soldiers or use a dynamic array (ArrayList) instead. You can append elements to an ArrayList using ArrayList.add(), and you don't need to know the expected size before filling it up.
The x should be greater than -1 and less than 4.
The stacktrace does not mention the Solder class, its in the conctructor of the Army class.
Any how, only knowing that the index should be within a range is not enough. As a programmer its your duty to validate the index before trying to access an element at that index.
if(index > 0 && index < array.length) {
//then only acess the element at index
Problem is the array soldiers is of size 0.
This line int x = ...; // user input implies that you are taking input in some fashion from the user and accessing the array with it. Are you checking this value to see that is in range (i.e., between 0 and 3)? If not, this may be why your testing works.
Edit: something like this might solve it for you:
public class Army {
public Team team;
public Vector<Soldier> soldiers;
public Army(Team p) {
soldiers = new Vector<Soldier>()
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers.add(new Soldier(this));
}
}
}
Judging by your other code, this sort of pattern will be useful in your Game object as well.

Categories

Resources