What's wrong with my code for the toString() method? [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
please note that I'm a complete beginner to programming and have found learning Java quite hard. I have a school task that requires me to write a code for a toString() method and I've blindly followed what my teacher has been writing/teaching in class but for some reason my code doesn't seem to work when I run the test file? I've included my code below.
I do get an error that says the following- "Null pointer access: The variable coef can only be null at this location" but when I change all my coef[] variables, then my code becomes moot because it just equates to null.
Any pointers greatly appreciated!
EDIT 1: Thank you for your responses - I thought I needed to intialise coef[] as a variable inside my toString() method (big oops!!). Also thank you for providing the link to the NullPointer question - it had some really thorough explanations and now I understand that I dereferenced the coeff[] variable.
QUERY a: I've removed my first line but now it seems that my code fails on this line return coef[1]+ "x + " + coef[0];
QUERY b: curious to know why it's a bad sign if the class is plural?
public class Polynomials {
public Double coefficient;
public Integer exponent;
private int[] coef;
public String toString() {
String[] coef = null;
if (exponent <= -1)
return "0";
else if (exponent == 0)
return "" + coef[0];
else if (exponent == 1)
return coef[1]+ "x + " + coef[0];
String s = coef[exponent] + "x^" + exponent;
return s;
}

Your Polynomials class has 3 fields, and one is called coef. In your toString method you then declare a local variable, also called coef.
In java, that means the local variable 'shadows' the field - in other words, for that entire method, coef refers to the String[] coef = null; and not the int[] coef.
And that local field is always null - you create it, initialize it to null, and never change it. Thus, choef[0] will guaranteed throw a NullPointerException at runtime.
The fix seems to be to .... just remove that String[] coef = null; line entirely. I have no idea why you wrote that or what it's trying to accomplish.
NB: Shouldn't the class be named Polynomial? Naming a class a plural is usually a bad sign.

Related

Variable declaration not allowed here, used in if statement [duplicate]

This question already has answers here:
JAVA Variable declaration not allowed here
(5 answers)
Closed 5 years ago.
After typing that first part of the if statement, I was going to use the next line to declare a variable (costPerCD) but I'm told "Variable declaration is not allowed here." I'm not sure how else to calculate the costPerCD without using this method. This is an example of what I'm trying to do. Any help would be appreciated.
if ((numCDs>=1 && (numCDs<=4))
double costPerCD= 20.99;
You should declare that variable as a class variable. Then you can access the variable throughout your class.
You need to add an additional ")" to your code after your first condition. This should prevent the error you are getting.
public class CDCal {
//Class Variable can be accessed in this class
private costPerCD;
public CDCal(){
//Assign value when object created
costPerCD = 20.99
}
public double calculateCost(int numCDs){
double total = 0;
if((numCDs >= 1) && (numCDs <= 4))
{
//Calculate total cost of CD's based on number and price
total = costPerCD * numCDs;
}
//Return the total at the end of the method.
Return total;
}
If you have an example I will be happy to review it to help you out.

Beginner Java Scope Issue [duplicate]

This question already has an answer here:
Beginner Java: Variable Scope Issue
(1 answer)
Closed 7 years ago.
I'm new to programming and seem to be running into issues with when a variable, class, etc can and can't be referenced. Below is an example, hoping one of you can fix the specific issue but also help me understand it more broadly so I don't run into it again and again.
to try and avoid posting a bunch of code please note that a Question class is defined as well as a setText, setAnswer, checkAnswer, and display method are all defined elsewhere (all public).
The relevant code is below and I have two questions:
Why is the variable first not recognized in the method presentQuestion()?
At the very end there, why can't I just call the method checkAnswer() on first, i.e. why can't I just do first.checkAnswer(response);? Why do I have to define it in a new variable: boolean outcome = first.checkAnswer(response);?
Code:
/**
* This program shows a simple quiz with two questions.
*/
public class QuestionDemo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Question first = new Question();
first.setText("Who was the inventor of Java?");
first.setAnswer("James Gosling");
Question second = new Question();
second.setText("Who was the founder of Udacity?");
second.setAnswer("Sebastian Thrun");
int score = 0;
score = score + presentQuestion(first, in);
// Present the second question
score = score + presentQuestion(second, in);
System.out.println("Your score: " + score);
}
/**
* Presents a question to the user and obtains a response.
* #param q the question to present
* #param in the scanner from which to read the user input
* #return the score (1 if correct, 0 if incorrect);
*/
public static int presentQuestion(Question q, Scanner in) {
// Display the first question
first.display();
System.out.println("Your answer:");
String response = in.nextLine();
// Check whether the response was correct
// If so, print "true" and return 1
// Otherwise, print "false" and return 0
boolean outcome = first.checkAnswer(response);
System.out.println(outcome);
if (outcome) {
return 1;
}
else {
return 0;
}
}
}
The reason you can't use the variable first inside presentQuestion is because it's defined in main, and therefore not visible outside of main. Isn't this precisely why you gave presentQuestion its Question q parameter, however?
It seems to me that this is what you want to do:
public static int presentQuestion(Question q, Scanner in)
{
// Display the first question
q.display();
System.out.println("Your answer:");
String response = in.nextLine();
// Check whether the response was correct
// If so, print "true" and return 1
// Otherwise, print "false" and return 0
boolean outcome = q.checkAnswer(response);
System.out.println(outcome);
if (outcome) {
return 1;
} else {
return 0;
}
}
Note that references to first have been replaced by references to q.
To try and clear up what I imagine your confusion may consist in, imagine if presentQuestion were called from another method than main, in which case no first variable would be declared at all. What would then happen to the references to first inside of presentQuestion, now not referring to anything at all? This is why you need to explicitly pass the data you want as parameters. Different methods are independent blocks of code, and you can't intermingle variable references between them even if they happen to call each other.
As for question 2, there should indeed be no problem with checking if(q.checkAnswer(response)) directly, without using the outcome variable. I'm guessing you were simply confused by the error emitted by the compiler when first wasn't recognized again.
first is a local variable, that means it can only be accessed inside the method in which it is defined.
You don't have to put the result of checkAnswer() into a boolean before using it. Actually, if (checkAnswer(response)) { ... } is valid.
presentQuestion takes a question as a parameter. In main, you're calling it on the first question, and then on the second question; it looks like the intent is that you use presentQuestion on the first question, and then on the second question. So far, so good.
The problem is that in presentQuestion, you're referring to the question (which could be the first or the second question) as q in the parameter list. All you need to do is use q instead of first in the rest of the method.
When I was new to programming, I had this problem as well! Then I found out it is very simple.
For your first question, first is declared in the main method and you want to use it in presentQuestion method. But presentQuestion and main are different methods! So you can't get to first in presentQuestion. As you can see, there is a Question-typed parameter in the presentQuestion method. This is like you telling first, "Come here, man! And then change your name to q." When you do pass the argument first to presentQuestion,
presentQuestion (first, in);
first comes to the pressentQuestion method with its name being as q. So you should use q instead of first in the presentQuestion method.
Now the second question, using a variable in this context is not needed. But to increase efficiency, use a boolean variable to store the result of checkAnswer. Let's imagine what happens if you don't use a boolean variable.
System.out.println(q.checkAnswer(response));
if (q.checkAnswer(response)) {
return 1;
} else {
return 0;
}
See? you called q.checkAnswer twice! This would slow down your program so you should use a boolean variable.

How did I get the result of '6.03' and '23.24'? - Java Parameter Return [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I wonder how did I get the result of '6.03' and '23.24'? System.out.println(a+b+c) does not add up to those 2 numbers?
Why is there a return c + "" + a? There is no output result show c + a?
The full code as follows:
MyProgram:
public class MyProgram
{
public void start()
{
String result;
result = lots(2+1, 3, "3");
result = lots(22, 1.2, "4");
}
private String lots(int a, double b, String c)
{
System.out.println(a+b+c);
return c + "" + a;
}
}
MyApplication:
public class MyApplication
{
public static void main (String[] args)
{
MyProgram p = new MyProgram();
p.start();
}
}
It makes sense because you're concatenating some string at the end of all of that math.
For the first run, you pass in 3 and 3.0 as your first two numerical parameters. That adds to 6.0 (it's been since upcast to double). You now then do string concatenation on 3 to arrive at 6.03 for your answer.
Trace through the second execution of the method to arrive at a similar answer. Remember: + is overloaded in Java to mean either numeric addition or string concatenation.
You overwrite result after you get it the first time, but even then, you don't do anything with it. I'd argue that you don't really need the return statement. If it were there, then you'd actually return the string 422*, since again, it's all string concatenation at that level.
*: This is from the last standing run if you printed it out after both were executed. If it were printed out each time, you'd see 22 first.
a+b+c is (a+b)+c
The first addition adds the two numbers.
The second addition converts the result of the addition into a string, then concatenates it with the final string.
So ((2+1) + 3) = 6.0
and 6.0 + "3" = "6.0" + "3" = "6.03"

if statement with integers [duplicate]

This question already has answers here:
Why does my if condition not accept an integer in java?
(7 answers)
Closed 3 years ago.
I'm new at Java. I'm looking for some help with homework. I wont post the full code I was doing that originally but I dont think it will help me learn it.
I have a program working with classes. I have a class that will validate a selection and a class that has my setters and getters and a class that the professor coded with the IO for the program (it's an addres book)
I have a statement in my main like this that says
//create new scanner
Scanner ip = new Scanner(System.in);
System.out.println();
int menuNumber = Validator.getInt(ip, "Enter menu number: ", 1, 3);
if (menuNumber = 1)
{
//print address book
}
else if (menuNumber = 2)
{
// get input from user
}
else
{
Exit
}
If you look at my if statement if (menuNumber = 1) I get a red line that tells me I cannot convert an int to boolean. I thought the answer was if (menuNumber.equals(1)) but that also gave me a similar error.
I'm not 100% on what I can do to fix it so I wanted to ask for help. Do I need to convert my entry to a string? Right now my validator looks something like:
if (int < 1)
print "Error entry must be 1, 2 or 3)
else if (int > 3)
print "error entry must 1, 2, or 3)
else
print "invalid entry"
If I convert my main to a string instead of an int wont I have to change this all up as well?
Thanks again for helping me I haven't been diong that great and I want to get a good chunk of the assignment knocked out.
if (menuNumber = 1)
should be
if (menuNumber == 1)
The former assigns the value 1 to menuNumber, the latter tests if menuNumber is equal to 1.
The reason you get cannot convert an int to boolean is that Java expects a boolean in the if(...) construct - but menuNumber is an int. The expression menuNumber == 1 returns a boolean, which is what is needed.
It's a common mix-up in various languages. I think you can set the Java compiler to warn you of other likely cases of this error.
A trick used in some languages is to do the comparison the other way round: (1 == menuNumber) so that if you accidentally type = you will get a compiler error rather than a silent bug.
This is known as a Yoda Condition.
In Java, a similar trick can be used if you are comparing objects using the .equals() method (not ==), and one of them could be null:
if(myString.equals("abc"))
may produce a NullPointerException if myString is null. But:
if("abc".equals(myString))
will cope, and will just return false if myString is null.
I get a red line that tells me I cannot convert an int to boolean.
Thats because = is an assignment operator. What you need to use is == operator.
A single equal sign is assignment: you assign value to a variable this way. use two equal signs (==) for comparison:
if ($menuNumber = 1) {
Update: forgot dollar sign: $menuNumber

How to multiply 10 to an "Integer" object in Java?

How do I multiply 10 to an Integer object and get back the Integer object?
I am looking for the neatest way of doing this.
I would probably do it this way:
Get int from Integer object, multiply it with the other int and create another Integer object with this int value.
Code will be something like ...
integerObj = new Integer(integerObj.intValue() * 10);
But, I saw a code where the author is doing it this way: Get the String from the Integer object, concatenate "0" at the end and then get Integer object back by using Integer.parseInt
The code is something like this:
String s = integerObj + "0";
integerObj = Integer.parseInt(s);
Is there any merit in doing it either way?
And what would be the most efficient/neatest way in general and in this case?
With Java 5's autoboxing, you can simply do:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);
The string approach is amusing, but almost certainly a bad way to do it.
Getting the int value of an Integer, and creating a new one will be very fast, where as parseInt would be fairly expensive to call.
Overall, I'd agree with your original approach (which, as others have pointed out, can be done without so much clutter if you have autoboxing as introduced in Java 5).
The problem with the second way is the way Strings are handled in Java:
"0" is converted into a constant String object at compile time.
Each time this code is called, s is constructed as a new String object, and javac converts that code to String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer for older versions). Even if you use the same integerObj, i.e.,
String s1 = integerObj + "0";
String s2 = integerObj + "0";
(s1 == s2) would be false, while s1.equals(s2) would be true.
Integer.parseInt internally calls new Integer() anyway, because Integer is immutable.
BTW, autoboxing/unboxing is internally the same as the first method.
Keep away from the second approach, best bet would be the autoboxing if you're using java 1.5, anything earlier your first example would be best.
The solution using the String method is not so good for a variety of reasons. Some are aesthetic reasons others are practical.
On a practical front more objects get created by the String version than the more normal form (as you have expressed in your first example).
On an aesthetic note, I think that the second version obscures the intent of the code and that is nearly as important as getting it to produce the result you want.
toolkit's answer above is correct and the best way, but it doesn't give a full explanation of what is happening.
Assuming Java 5 or later:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20
What you need to know is that this is the exact same as doing:
Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20
By performing the operation (in this case *=) on the object 'a', you are not changing the int value inside the 'a' object, but actually assigning a new object to 'a'.
This is because 'a' gets auto-unboxed in order to perform the multiplication, and then the result of the multiplication gets auto-boxed and assigned to 'a'.
Integer is an immutable object. (All wrapper classes are immutable.)
Take for example this piece of code:
static void test() {
Integer i = new Integer(10);
System.out.println("StartingMemory: " + System.identityHashCode(i));
changeInteger(i);
System.out.println("Step1: " + i);
changeInteger(++i);
System.out.println("Step2: " + i.intValue());
System.out.println("MiddleMemory: " + System.identityHashCode(i));
}
static void changeInteger(Integer i) {
System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
System.out.println("ChangeStartValue: " + i);
i++;
System.out.println("ChangeEnd: " + i);
System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}
The output will be:
StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
You can see the memory address for 'i' is changing (your memory addresses will be different).
Now lets do a little test with reflection, add this onto the end of the test() method:
System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
final Field f = i.getClass().getDeclaredField("value");
f.setAccessible(true);
f.setInt(i, 15);
System.out.println("Step3: " + i.intValue());
System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
e.printStackTrace();
}
The additional output will be:
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
You can see that the memory address for 'i' did not change, even though we changed its value using reflection.
(DO NOT USE REFLECTION THIS WAY IN REAL LIFE!!)

Categories

Resources