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

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.

Related

Question about the behavior of toString on integers

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

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");
}

Splitting a string that has numbers and characters into an int and String

I have a String that goes "Peyton Manning; 49". Is there a way to have the computer read the left side of the String and make it equal to a new String "Peyton Manning" and take the right side of the String and make it equal to an int with a value of 49?
A number of ways spring to mind: you can tokenize or you can use regexs. You didn't specify about white space padding. Also, you didn't specify if the string segments around the delimiter can be invalid integers, mixtures strings digits etc. If this helped you, please mark accordingly.
public class Test {
public static void main(String[] args) {
String s="Blah; 99";
StringTokenizer st = new StringTokenizer(s, ";");
String name = st.nextToken();
Integer number = Integer.parseInt(st.nextToken().trim());
System.out.println(name.trim() + "---" + number);
number = Integer.parseInt(s.replaceAll("[^0-9]", ""));
name = s.replaceAll("[^A-Za-z]", "");
System.out.println(name + "---" + number);
int split = s.indexOf(";");
name = s.substring(0, split);
number = Integer.parseInt(s.substring(split+2, s.length()));
System.out.println(name + "---" + number);
}
}
The simplest way is:
String text = input.replaceAll(" *\\d*", "");
int number = Integer.parseInt(input.replaceAll("\\D", ""));
See KISS principle.

The string is getting the wrong value

I am trying to build a string like 11 11 but I am facing problem I am getting for start the following string 98 11 and not 11 11.
How can I fix that?
I appreciate any help.
Character number = newName.charAt(2); //here number is 1
Character numberBefore = newName.charAt(1); //here numberBefore is 1
try (PrintWriter writer = new PrintWriter(path+File.separator+newName);
Scanner scanner = new Scanner(file)) {
boolean shouldPrint = false;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(numberBefore >0 ){
String start= number+number+" "+number+number; //here start is `98 11`
}
Yes, this is due to the associativity of +.
This:
String start= number+number+" "+number+number;
is effectively:
String start = (((number + number) + " ") + number) + number;
So you're getting number + number (which is performing numeric promotion to int) and then string concatenation.
It sounds like you want:
String numberString = String.valueOf(number);
String start = numberString + numberString + " " + numberString + numberString;
Or alternatively:
String start = String.format("%0c%0c %0c%0c", number);
yes this is because of associativity of +
you can try the below code also
String c1 =Character.toString(number);
String s =c1+c1+" "+c1+c1;
String newName = "111";
Character number = newName.charAt(2); // here number is 1
Character numberBefore = newName.charAt(1); // here numberBefore is 1
if (Character.getNumericValue(numberBefore) > 0) { // checking against numeric rather than ascii
System.out.println("ASCII value of char " + (int) number); // ASCII code for '1' = 49
String start = String.valueOf(number) + String.valueOf(number) + " " + number + number; // here start is `98 11`
System.out.println(start);
}
}

Printing a substring, if the string contains information given from scanner input. (Java)

Here is what I have:
Scanner input = new Scanner(System.in);
System.out.print("Enter an uppercase letter: ");
String Letter = input.next();
String LettersTwo = "A" + "B" + "C";
String DigitTwo = LettersTwo.substring(0) + "2";
String LettersThree = "D" + "E" + "F";
String DigitThree = LettersThree.substring(0) + "3";
String LettersFour = "G" + "H" + "I";
String DigitFour = LettersFour.substring(0) + "4";
String LettersFive = "J" + "K" + "L";
String DigitFive = LettersFive.substring(0) + "5";
String LettersSix = "M" + "N" + "O";
String DigitSix = LettersSix.substring(0) + "6";
String LettersSeven = "P" + "Q" + "R" + "S";
String DigitSeven = LettersSeven.substring(0) + "7";
String LettersEight = "T" + "U" + "V";
String DigitEight = LettersEight.substring(0) + "8";
String LettersNine = "W" + "X" + "Y" + "Z";
String DigitNine = LettersNine.substring(0) + "9";
if (Letter.contains(LettersTwo)) {
System.out.println("The corresponding digit is " + DigitTwo);
}
If the user inputs an uppercase letter of A, B, or C, I want the system to print out, "The corresponding number is 2". I correlated the number to the uppercase letter in substrings. The system isn't printing that out and what I have it as is if Letter contains something from LettersTwo, then to print that out. I am new to programming though so I don't know if I have that written correctly. Can someone help me get this working?
Take another look at your if statement:
if (Letter.contains(LettersTwo))
Here you're checking to see if a single letter contains a string of letters. Logically that'll return false. But if you use it this way:
if (LettersTwo.contains(Letter))
You're checking if a group of letters contains a single letter.
The most obvious approach is to use an if statement or switch statement. Anther approach, which seems to be what you are trying to do, is to use an array of String. (Note that when you start adding numbers to the end of a variable name, this is a strong indication that you should use an array.) If you want to get fancy, you can turn this into a lookup table with a Map<Character, Integer>.
You should also look at the documentation for String.contains(). It doesn't work the way you are trying to use it.

Categories