Question about the behavior of toString on integers - java

Why does an integer alone in returning a String not work, but it does work when adding a String next to it?
Does it suddenly convert the integer like with something as (Integer.toString())?
public class Car {
String brand;
String model;
int hp;
#Override
public String toString() {
return hp; //this doesn't work because it wants to return int.
//return hp + brand; does work for some reason.
/*return Integer.toString(hp); could it be doing something like this behind
the scenes?*/
}}

According to the Java Language Specification:
String contexts apply only to an operand of the binary + operator which is not a String when the other operand is a String.
The target type in these contexts is always String, and a string conversion (ยง5.1.11) of the non-String operand always occurs.
Which means that when you do hp + brand, since brand is a String the rule above kicks in, hp gets converted to a String and concatenation occurs, resulting in a String.

This is because of the way Java handles strings. When you try to 'add' anything to a string, it results in a 'concatenate' operation. Here is a good article that explains it https://www.geeksforgeeks.org/addition-and-concatenation-using-plus-operator-in-java/
For example:
int n1 = 10;
int n2 = 20;
int n3 = 30;
int n4 = 40;
// Below statement will print the sum 100 as all operands are `int`
System.out.println(n1 + n2 + n3 + n4);
// Introducing a string changes the behavior
System.out.println(n1 + "" + n2 + n3 + n4); // Will print 10203040 (concatenated)
Also worth noting is that the expressions are evaluated from left-to-right. See below:
System.out.println(n1 + n2 + "" + n3 + n4); // Will print 303040

Related

How to convert a String into an integer, double, boolean (same signature)?

It is possible to convert a String in this way? We have same paramater and Java makes the right choise. If the value is an integer - we call parseInt(value), else if the value is an double - we call parseDouble(value) or the value is an boolean - we call parseBoolean(value);
public int parseInt(String value) {
int newValue = Integer.valueOf(value).intValue();
return newValue;
}
public double parseDouble(String value) {
double newValue = Double.valueOf(value).doubleValue();
return newValue;
}
public boolean parseBoolean(String value) {
boolean newValue = Boolean.valueOf(value).booleanValue();
return newValue;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ConvertStrings convert = new ConvertStrings();
System.out.println("Enter the value:");
String value = sc.next();
//If value is an Integer - we call parseInt(value);
//If value is an double - we call parseDouble(value);
//If value is an boolean - we call parseBoolean(value);
sc.close();
}
Scanner has really helpful methods exactly for this like hasNextInt(), hasNextLong(), hasNextBoolean(). So you can use those :).
Scanner scanner = new Scanner(System.in);
if (scanner.hasNextBoolean()) {
boolean nextBoolean = scanner.nextBoolean();
} else if (scanner.hasNextInt()) {
boolean nextInt = scanner.nextInt();
}
If you only have the String (i.e., "value" was obtained elsewhere), you could do this:
try {
int ival = Integer.valueOf(value);
... // do something with the int
} catch (NumberFormatException ei)
// it isn't an integer, so try it as a double
try {
double dval = Double.valueOf(value);
... // do something with it
} catch ( NumberFormatException ed ) {
// Not a double, either. Assume it is boolean
boolean b = Boolean.valueOf(value);
...
}
}
Just so you know, there is a subtle difference between the Integer.valueOf() and Integer.parseInt() methods. Although not overly important since Autoboxing was introduced in Java 1.5 it is still worth noting for specific reasons described here. After all, the Integer.valueOf() method utilizes the Integer.parseInt() method within its method code anyways. Other good reads with regards to this can be found in this SO Post and in this SO Post.
I don't know what version of Java you are coding with but the unboxing as used in:
Integer.valueOf(value).intValue();
is unnecessary.
Since you're methods are returning a primitive data type, I would use the .parseXxx..(), type methods from the Integer class instead of the valueOf() method unless of course you want to take advantage of the caching mechanism available with the valueOf() method:
public int parseInt(String value) {
int newValue = Integer.parseInt(value);
return newValue;
}
But I would take it a step further and validate the fact that the supplied string argument via the value parameter was indeed a numerical value. Even though you would normally do this before calling a method like parseInt(), I don't think it hurts to have it just in case a pre-validation wasn't done. I would use the String#matches() method along with a Regular Expression (RegEx) for this, for example:
public int parseInt(String value) {
// Does value contain a signed or unsigned Integer
// type string numerical value?
if (!value.matches("-?\\d+")) {
//No - Throw an Exception.
throw new IllegalArgumentException(this.getClass().getName()
+ ".parseInt() - Invalid numerical value supplied (" + value + ")!");
}
// Yes - Convert numerical string to a primitive int value.
int newValue = Integer.parseInt(value);
return newValue;
}
As time goes on you may find that using the Integer class methods directly rather than through yet another method would be easier and more beneficial. This of course would depend entirely upon what you are doing.
For your methods, you may want to try this:
public int parseInt(String value) {
if (!value.matches("-?\\d+")) {
throw new IllegalArgumentException(this.getClass().getName()
+ ".parseInt() - Invalid numerical value supplied (" + value + ")!");
}
int newValue = Integer.parseInt(value);
return newValue;
}
public double parseDouble(String value) {
if (!value.matches("-?\\d+(\\.\\d+)?")) {
throw new IllegalArgumentException(this.getClass().getName()
+ ".parseDouble() - Invalid numerical value supplied (" + value + ")!");
}
double newValue = Double.parseDouble(value);
return newValue;
}
public float parseFloat(String value) {
if (!value.matches("-?\\d+(\\.\\d+)?")) {
throw new IllegalArgumentException(this.getClass().getName()
+ ".parseFloat() - Invalid numerical value supplied (" + value + ")!");
}
float newValue = Float.parseFloat(value);
return newValue;
}
public boolean parseBoolean(String value) {
value = value.toLowerCase();
boolean newValue = false;
if (value.matches("true")
|| value.matches("false")
|| value.matches("yes")
|| value.matches("no")) {
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) {
newValue = true;
}
}
return newValue;
}
To use these methods you might do something like this:
Scanner sc = new Scanner(System.in);
//ConvertStrings convert = new ConvertStrings(); // Don't know what this class does.
String ls = System.lineSeparator();
int aINT;
double aDOUBLE;
float aFLOAT;
boolean aBOOLEAN;
String value = "";
while (!value.equals("q")) {
System.out.print("Enter a value (q to quit): --> ");
value = sc.nextLine();
if (value.equalsIgnoreCase("q")) {
break;
}
if (value.equals("")) {
System.out.println(">> Invalid Entry! You must enter a String! <<" + ls);
continue;
}
if (value.matches("-?\\d+")) {
aINT = parseInt(value);
System.out.println("A Integer (int) value of " + aINT + " was supplied." + ls);
}
else if (value.matches("-?\\d+(\\.\\d+)?([df])?")) {
if (value.matches("-?\\d+(\\.\\d+)?d")) {
aDOUBLE = parseDouble(value.toLowerCase().replace("d", ""));
System.out.println("A Double (double) value of " + aDOUBLE + " was supplied." + ls);
}
else if (value.matches("-?\\d+(\\.\\d+)?f")) {
aFLOAT = parseFloat(value.toLowerCase().replace("f", ""));
System.out.println("A Float (float) value of " + aFLOAT + " was supplied." + ls);
}
else {
aDOUBLE = parseDouble(value);
System.out.println("A Double/Float (double/float) value of " + aDOUBLE + " was supplied." + ls);
}
}
else if (value.toLowerCase().matches("true")
|| value.toLowerCase().matches("yes")
|| value.toLowerCase().matches("false")
|| value.toLowerCase().matches("no")) {
aBOOLEAN = parseBoolean(value);
System.out.println("A Boolean (boolean) value of '" + aBOOLEAN + "' was supplied." + ls);
}
else {
System.out.println("A String was supplied! (\"" + value + "\")" + ls);
}
}
In the above example code the following string values can be supplied:
A string of any size which would ultimately return and display that
string if it's not a numerical value.
A String representation of a signed or unsigned Integer type
numerical value.
A String representation of a signed or unsigned Double/Float type
numerical value.
A String representation of a signed or unsigned Double type numerical
value followed by the 'd' designation, for example: "453.665d" or
"3236d".
A String representation of a signed or unsigned Float type numerical
value followed by the 'f' designation, for example: "127.33f" or
32f.
A String representation of a Boolean type value, for example:
"true" or "yes" or "false" or "no".
Regular Expressions used in code:
The parseInt() method:
if (!value.matches("-?\\d+")) {
A Integer value. If the String held within the variable value matches to be a signed or unsigned integer numerical type value containing one or more digits.
The parseDouble() and parseFloat() methods:
if (!value.matches("-?\\d+(\\.\\d+)?")) {
A Double or Float value. If the String held within the variable value matches to be a signed or unsigned Integer or Double/Float Type numerical value containing one or more digits.
In example run code:
else if (value.matches("-?\\d+(\\.\\d+)?([df])?")) {
A Double or Float value. If the String held within the variable value matches to be a signed or unsigned Integer or Double/Float Type numerical value containing one or more digits and contains the letter d OR the letter f at the end.
In example run code:
if (value.matches("-?\\d+(\\.\\d+)?d")) {
A Double value. If the String held within the variable value matches to be a signed or unsigned Integer or Double/Float Type numerical value containing one or more digits and contains the letter d at the end (as in: 345d or 343.42d).
In example run code:
if (value.matches("-?\\d+(\\.\\d+)?f")) {
A Float value. If the String held within the variable value matches to be a signed or unsigned Integer or Double/Float Type numerical value containing one or more digits and contains the letter f at the end (as in: 345f or 343.42f).

Java adding "0" at the end of the number

So my problem was such that I had to compute 10^n such that n ~ 10^5. Obviously it wouldn't fit in any data type hence I decided to use a string instead.
Finally, I did find the solution in the beginners book
https://beginnersbook.com/2014/07/java-right-padding-a-string-with-spaces-and-zeros/.
I don't want the BigInteger solution of multiplying 10 n times.
public class PadRightExample2 {
public static void main(String[] argv) {
System.out.println("#" + rightPadZeros("mystring", 10) + "#");
System.out.println("#" + rightPadZeros("mystring", 15) + "#");
System.out.println("#" + rightPadZeros("mystring", 20) + "#");
}
public static String rightPadZeros(String str, int num) {
return String.format("%1$-" + num + "s", str).replace(' ', '0');
}
}
Output:
#mystring00#
#mystring0000000#
#mystring000000000000#
Can anybody explain what is %1$- and what is s used for ?
% stands for the format of String
1$ means the first additional parameter args of String.format(String format, Object... args), 2$ would be the second one, etc..
- is the left justification, in connection with number declares the length of the final output, briefly said. The documentation of java.util.Formatter explains is a bit better:
Left justifies the output. Spaces ('\u0020') will be added at the end of the converted value as required to fill the minimum width of the field.
s stands for the String parameter type
The typical example is logging, where you parse the arguments with %s which is practically the same. With a dollar character and number %1$s you specify the argument number and -10 makes the final output length of 10.
#mystring00# // mystring00 has length 10
#mystring0000000# // mystring0000000 has length 15
#mystring000000000000# // #mystring000000000000 has length 20
Most of the information could be found in the documentation of java.util.Formatter, which is used within String::format.
The snippet you have found might be a bit confusing because it works even without 1$ because the arguments are passed in order.
Try the following: String.format("%2$-" + num + "s", str, "test").replace(' ', '0');. The result will be
#test000000#
#test00000000000#
#test0000000000000000#
Whereas String.format("%1$-" + num + "s", str, "test").replace(' ', '0'); leads to the original result from your snippet. Notice the 1$ and 2$ difference.
Maybe I'm not understanding the question correctly, but cant you do:
public static String rightPadZeros(String str, int num) {
String add = "";
for(int i = 0; i < num;i++) add += "0";
return str + add;
}
I dont quite understand why you would want two zeros when num=10, but if you want that, do:
public static String rightPadZeros(String str, int num) {
String add = "";
for(int i = 0; i < num - 8;i++) add += "0";
return str + add;
}
EDIT: apparenetely that was bad for performance, so this might be better:
public static String rightPadZeros(String str, int num) {
return str + new String(new char[num]).replace("\0", "0");
}

Add two numbers instead of combining

I am trying to create a program in which a user can enter 2 numbers and the program will take the 2 numbers and multiply them to get an answer. However, for this specific example, I am simply trying to take 2 numbers from a user and I want Java to add them. eg 1+1=2, instead of 1+1=11.
My code:
import javax.swing.JOptionPane;
public class MultiplicationTables {
public static void main(String args[]) {
//declare variables
String num1;
String num2;
int ans=0;
num1=JOptionPane.showInputDialog(null,"Enter a number");
num2=JOptionPane.showInputDialog(null,"Enter another number");
ans=Integer.parseInt(num1);
ans=Integer.parseInt(num2);
JOptionPane.showMessageDialog(null,"Your answer is " + (num1+num2));
}
}
num1 and num2 are String.
So as you write num1+num2 you get the result of their concatenation.
In fact, you don't use the Integer.parseInt(); results.
Instead, do it to addition two int values:
int result = Integer.parseInt(num1) + Integer.parseInt(num2);
And display result :
JOptionPane.showMessageDialog(null,"Your answer is " + result);
You are using num1 and num2 which are Strings instead of ans which should be your sum as an int.
Also you don't add correctly the 2 values into ans.
public static void main(String args[]){
String num1 = JOptionPane.showInputDialog(null,"Enter a number");
String num2 = JOptionPane.showInputDialog(null,"Enter another number");
int ans = Integer.parseInt(num1);
ans += Integer.parseInt(num2);
JOptionPane.showMessageDialog(null,"Your answer is " + ans);
}
Here:
num1=JOptionPane.showInputDialog(null,"Enter a number");
num2=JOptionPane.showInputDialog(null,"Enter another number");
The option pane returns strings, what you seem to understand, as you then go:
ans=Integer.parseInt(num1);
ans=Integer.parseInt(num2);
But then you use the + operator on your string results:
... +(num1+num2));
But + for strings concatenates them.
So instead of "adding" strings, you want to add the numbers, as in:
int1FromUser = Integer.parseInt(num1);
int2FromUser = Integer.parseInt(num2);
int sum = int1FromUser + int2FromUser;
That is all there is to this.
( and I took the freedom to use slightly better naming - keep in mind to use variable names that say something about the meaning of the thing they point to )
You are doing it wrong. You are adding Strings in the end and ignoring the parsed Integers.
And also you using the same integer variable for both inputs.
So that should be
int ans1=0;
int ans2=0;
...
ans1=Integer.parseInt(num1);
ans2=Integer.parseInt(num2);
And in the end
JOptionPane.showMessageDialog(null,"Your answer is " +(ans1+ans2));
+ is used in addition when using Integer or int, and it also used to concatenate two Strings. In your case num1 and num2 are Strings, and hence it is concatenating the result. So you will have to change your code to reflect following changes:
ans = Integer.parseInt(num1);
ans += Integer.parseInt(num2); // add the result of parseInt to ans
//--^---------------------------
JOptionPane.showMessageDialog(null,"Your answer is " + ans ); // another one
Or alternatively:
JOptionPane.showMessageDialog(null,"Your answer is " + (Integer.parseInt(num1) + Integer.parseInt(num2)));
I'd suggest you change the last line of your method to:
JOptionPane.showMessageDialog(null,"Your answer is " + (Integer.parseInt(num1) + Integer.parseInt(num2)));
This way, you don't need the "ans" variable (which in your code doesn't really do anything) at all. Instead, you can simply parse the int values and add them on the same line as you're writing the message.
If you want to use ans, try this:
ans = Integer.parseInt(num1) + Integer.parseInt(num2);
Then:
JOptionPane.showMessageDialog(null,"Your answer is " + ans);

How do I pass sorted integers into JOptionPane?

I'm trying to write an application that inputs three integers from the user and displays the sum, average, product, smallest and largest of the numbers. It also should print the three numbers in an ascending order (from smallest to the largest). I tried to return the results into one JOptionPane but the sortResult is not returning the user inputs. I probably tried to over simplify the sort algorithm and am not applying it correctly. Currently the sortResult is returning a jumbled string:
"Your numbers are: [l#23ab93od"
What is the easiest way to correct this? Here is the code:
// Calculations using three integers.
import java.util.Arrays;
import javax.swing.JOptionPane;
public class Calculations {
public static void main( String args[] ){
int x;// first number
int y;// second number
int z;// third number
int sumResult;// sum of numbers
int avgResult;// average of numbers
int prodResult;// product of numbers
int maxResult;// max of numbers
int minResult;// min of numbers
String xVal;// first string input by user
String yVal;// second string input by user
String zVal;// third string input by user
xVal = JOptionPane.showInputDialog("Enter first integer:");// prompt
yVal = JOptionPane.showInputDialog("Enter second integer:");// prompt
zVal = JOptionPane.showInputDialog("Enter third integer:");// prompt
x = Integer.parseInt( xVal );
y = Integer.parseInt( yVal );
z = Integer.parseInt( zVal );
sumResult = x + y + z;
avgResult = sumResult/3;
prodResult = x * y * z;
maxResult = Math.max(x, Math.max(y, z));
minResult = Math.min(x, Math.min(y, z));
int[] sortResult = {x, y, z};
Arrays.sort(sortResult);
String result;
result = "Your numbers are: " + sortResult +
"\n" + "The sum is " + sumResult +
"\n" + "The average is " + avgResult +
"\n" + "The product is " + prodResult +
"\n" + "The max is " + maxResult +
"\n" + "The min is " + minResult;
JOptionPane.showMessageDialog(null, result, "Results", JOptionPane.INFORMATION_MESSAGE );
System.exit(0);
}// end method main
}// end class Product
When you concatenate an object with a String, Java automatically converts to a string by using its toString method. The array type does not override the toString method, so when toString is used on it, it will use Object's toString method, which just returns the type of the object ([l is the type of an array of ints) # its hash code in hex.
To get a String that represents what an array contains, use Arrays.toString(arrayName), (in this case "Your numbers are: " + Arrays.toString(sortResult) + ...).
Also, since you know that your array contains three elements, you could also just use something like sortResults[0] + ", " + sortResults[1] + ", " + sortResults[2], if you wanted them to be in a different format that the one returned by Arrays.toString (if you did not know the number of elements, or had too many to type them all one by one, you would have to loop through them).
You can use Arrays.toString(array) or the other nice thing you can do is to use collection framework.
Here I am giving you an example
ArrayList<Integer> al = new ArrayList<>();
// to add three element or to do any common thing for any number of elements.
for(int i = 0; i < 3; i++)
al.add(JOptionPane.showInputDialog("Enter " + i + "th number:"));
System.out.println(al);
By using Collections provided by java, you can make sorting, finding max, min, etc very easy.
// finding minimum of all elements
Integer min = al.stream().min((Integer a, Integer b) -> a.compareTo(b));
// finding maximum of all elements
Integer max = al.stream().max((Integer a, Integer b) -> a.compareTo(b));
// sorting all elements
al.sort((Integer a, Integer b) -> a.compareTo(b));

Why does a concatenation of integers and strings behave like this?

This code:
public void main(String[] args)
{
String s1 = 50+40+"Hello"+50+50;
System.out.println(s1);
}
Gives output of: 90Hello5050
Why?
It's just a matter of precedence and associativity. Your code is equivalent to:
String s1 = (((50 + 40) + "Hello") + 50) + 50;
So that's:
String s1 = ((90 + "Hello") + 50) + 50;
which is:
String s1 = ("90Hello" + 50) + 50;
which is:
String s1 = "90Hello50" + 50;
which is:
String s1 = "90Hello5050";
If you wanted 90Hello100 you should use brackets to make it explicit. I'd write it as:
String s1 = (50 + 40) + "Hello" + (50 + 50);
According to the Java Language Specification, Section 15.7, "Evaluation Order", operators in Java are evaluated from left to right.
That means that your concatenation is evaluated like it was written as
String s1 = (((50+40)+"Hello")+50)+50;
That's why it
adds 50 and 40 to yield 90
adds 90 and "Hello" to yield "90Hello"
adds "90Hello" and 50 to yield "90Hello50"
adds "90Hello50" and 50 to yield "90Hello5050"
In general, when you have a binary operation (like "+" in this case) that can be applied to a String and the computation involves a String, the other operand is converted into a String as well.
Because Java will concat your string from left to right. and it will add 50 and 40 with each other because they are int and then concat that to "hello" string and result is str because int and str will be str output. then "90hello" is str and it will contact with 50 which is int and the result as I said will be str and continue.

Categories