why can't I add chars to a new string? - java

code:
String st = "abc";
String sl = st.charAt(0)+st.charAt(st.length()-1));
The second line is wrong for some reason and I don't know why

The book is wrong, and Eclipse is right.
In Java, you can write "abc" + whatever, or whatever + "abc", and it concatenates the strings -- because one side is a String.
But in st.charAt(0)+st.charAt(st.length()-1)), neither side is a String. They're both chars. So Java won't give you a String back.
Instead, Java will actually technically give you an int. Here are the gritty details from the Java Language Specification, which describes exactly how Java works:
JLS 4.2 specifies that char is considered a numeric type.
JLS 15.18.2 specifies what + does to values of numeric types.
In particular, it specifies that the first thing done to them is binary numeric promotion, which converts both chars to int by JLS 5.6.2. Then it adds them, and the result is still an int.
To get what you want to happen, probably the simplest solution is to write
String sl = st.charAt(0) + "" + st.charAt(st.length() - 1));

Because charAt returns char [ int ]
use this code :
String st = "abc";
StringBuilder str = new StringBuilder();
str.append(st.charAt(0));
str.append(st.charAt(st.length() - 1));
System.out.println(str.toString());
append method accept the char, or string, ..

well this is what it says: "- Type mismatch: cannot convert from int to String"
Meaning exactly what #Jaime said. If I remember correctly, a char is technically represented by an integer value. (i.e. 'a' + 1 = 'b'). So you're adding two char values, which isn't the same thing as adding two strings together, or even concatenating two char values. One fix would be to use String.valueOf(st.charAt(0)) + String.valueOf(st.charAt(st.length()-1))) to concatenate the two char values.

Related

How to concatenate chars rather than add the numeric values

How to connect char number with char number?
My code is:
String room = "901";
// I want to a new String "01" so i do this
String roomNum = room.charAt(1) + room.charAt(2); // it's error
String roomNum = h.charAt(0).concat(h.charAt(1)); // error too
When I use String.valueOf() it gives me an ASCII.
String room = "901";
//I want to a new String "01":
Use:
room.subString(1);
String#subString(int) returns substring starting with int and ending with the last character.
For more subString overloads, have a look at String API.
If you want to concatenate two chars, you can do:
String room = "901";
char a = room.charAt(1);
char b = room.charAt(2);
String result = String.valueOf(a).concat(String.valueOf(b));
Otherwise, String roomNum = 'a'+'b'; will not compile, as the result of adding Java chars, shorts, or bytes is an int.
Beware, that char represents an Unicode Character (in Java, 16-bits each). So, each char value, under the hood, is encoded by numeric value, which is stored as a hexadecimal, decimal or other radix-system number. This is the main reason, why arithmetic operation on char value promotes to int.
While using substring will solve the problem (as in the answer of #Giorgi Tsiklauri), this doesn't point to the real hidden question posted that is:
Why a concatenation between chars is not the same of a concatenation of two strings of size 1 ?
That happens because the + symbol doesn't work as a concatenation in this context.
When you apply the + operator on chars a conversion to int is done before the operation. This operation is called Binary Numeric Promotion. From the second point in the JLS:
Widening primitive conversion (Β§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
So if you want to sum the string value of the 0 char and the string value of the 1 char you explicitly need to convert them in string as follow:
String room = "901";
String roomNumber = String.valueof(room.charAt(1)) + String.valueof(room.charAt(2));
If you do that the + operator is considered a concatenation between strings and not as a sum between int.

How should I represent a single unicode character in Java?

I would like to represent a single Unicode character in Java. Which primitive or class that is appropriate for this?
Note that I want to be able to store any unicode character, which may be too large for a 2 byte char.
char is indeed 16-bit, a char corresponds to a UTF-16 code unit. Characters that don't fit in a single UTF-16 code unit (Emojis, for instance) require two chars.
If you need to store them individually for some reason, you can use an int for that. It has sufficient room (and then some) for all of the 0x10FFFF code points currently allowed in Unicode. That's what the JDK uses, for instance in Character.codePointAt(CharSequence seq, int index) and String(int[] codePoints, int offset, int count).
Gratuitous conversion example (live on ideone):
String s = "πŸ˜‚";
int emoji = Character.codePointAt(s, 0);
String unumber = "U+" + Integer.toHexString(emoji).toUpperCase();
System.out.println(s + " is code point " + unumber);
String s2 = new String(new int[] { emoji }, 0, 1);
System.out.println("Code point " + unumber + " converted back to string: " + s2);
System.out.println("Successful round-trip? " + s.equals(s2));
which outputs:
πŸ˜‚ is code point U+1F602
Code point U+1F602 converted back to string: πŸ˜‚
Successful round-trip? true
Depends on the definition of a character:
If you mean one single Unicode code point, use int, which can hold every value from U+0000 to U+1FFFFF.
However, in some cases what appears as one character occupies multiple code points. This is especially common with emoji, eg.
skin tone: πŸ™‹πŸ» πŸ™‹πŸΏ
country flags: πŸ‡―πŸ‡΅ πŸ‡ΊπŸ‡Έ
families: πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦, which becomes "πŸ‘¨+πŸ‘©+πŸ‘§+πŸ‘¦" if I replace the zero-width joiners (U+200D) with plus signs.
To store those the most logic way is using a String.

building a hex value from integers

i am trying to generate a hex color value from an integer input, and I'm not sure I'm using the concat method correctly. when i output the string theColor, i only get "0x", any ideas?
public String generateColor(String redVal, String blueVal,
String greenVal, String alphaVal){
String theColor = "0x";
theColor.concat(alphaVal);
theColor.concat(redVal);
theColor.concat(greenVal);
theColor.concat(blueVal);
return theColor;
}
You will need to reassign it to the theColor as concat() method returns a string with concatenation.
like
theColor = theColor.concat(alphaVal);
String's concat does not modify the original String (Strings are immutable in Java). I'd suggest using a StringBuilder here:
public String generateColor(String redVal, String blueVal, String greenVal, String alphaVal) {
StringBuilder theColor = new StringBuilder("0x")
.append(alphaVal)
.append(redVal)
.append(greenVal)
.append(blueVal);
return theColor.toString();
}
String objects in java are immutable that is operations like concat do not modify original object but create new. You need modify you code to assign modified value to theColor:
theColor = theColor.concat(alphaVal);
If your input strings are all 2-character strings with two hex digits, then you can generate the string you want really simply:
public String generateColor(String redVal, String blueVal,
String greenVal, String alphaVal) {
return "0x" + alphaVal + redVal + greenVal + blueVal;
}
No need to fool around with StringBuilder or concat.
If the input strings have been converted from integers, so that you're not sure that they are two hex digits, then the above won't work. But solutions using concat or StringBuilder's append won't work either, since they essentially do the same thing as + -- they just concatenate all the strings together.
The first question to ask is, are you converting the integers to Strings too early? If you convert the integers to strings, then you pass the strings as parameters to generateColor, and then you are concerned that the strings aren't already in the right format, then you really ought to be passing your integers to generateColor, instead of the strings, and letting generateColor convert them to the kinds of strings you need. There are several ways to do this; here's one:
public String generateColor(int redVal, int blueVal,
int greenVal, int alphaVal) {
return String.format("0x%02x%02x%02x%02x", alphaVal & 0xFF,
redVal & 0xFF, greenVal & 0xFF, blueVal & 0xFF);
}
%02x says to format the next parameter in hex (the x), into a string 2 characters wide (the 2), and padding with leading zeros instead of blanks if the value is only one hex digit (the 0). If the integer value is too big to fit into two digits, format will include three or more characters in the string, which is why I used & 0xFF on each integer to ensure that the value will not be too big. %02x does not put an 0x at the front. The format string has its own 0x to put those two characters into the result. (If desired, you can use %02X instead of %02x, which causes the hex digits A-F to appear in upper case.)
There are other ways: you could create one int from the four input integers using &, | and << bit operators, and use "0x%08x" as the format string. And there are methods besides String.format that are capable of generating hex integers.

Convert XSLT function (string-to-codepoints) to Java

How can I "translate" this XSLT code to Java ?
<xsl:value-of select="number(string-to-codepoints(upper-case($char)) - string-to-codepoints('A'))+10"/>
I only know that: "The fn:string-to-codepoints function returns a sequence of xs:integer values representing the Unicode code points."
From the example that is given in (http://www.xsltfunctions.com/xsl/fn_string-to-codepoints.html) :
string-to-codepoints('a') = 97
I found this:
char ch = 'a';
System.out.println(String.format("\\u%04x", (int) ch));
But I get : \u0061
For a single char you can just cast it to int to get the decimal value:
System.out.println((int)ch);
For a String there's .toCharArray() to convert it to a char[] but that isn't quite the same as a "sequence of codepoints" if the String involves Unicode characters outside the BMP (i.e. above U+FFFF), which are represented in Java as a surrogate pair of two char values. To handle surrogates properly you would need to use a technique like the one described in this answer.
To answer the specific question you ask, you can do
number(string-to-codepoints(upper-case($char)) - string-to-codepoints('A'))+10
in Java as
char ch = // wherever you get $char from
int num = Character.toUpperCase(ch) - 'A' + 10;
since char is an integer type in Java and you can add or subtract char values like any other number.
But this will probably only give you a sensible answer when the initial ch is an ASCII letter.
You print the value as unicode escape sequence; XSLT prints a decimal value.
This should work much better:
System.out.println("a".codePointAt(0));

How can I do this int to String transformation?

I want to transform an int to a String such that:
0 -> "a"
1 -> "b"
2 -> "c"
and so on...
How can I do this?
You can convert from the character literal:
int input = 0;
String output = new Character((char) (input + 'a')).toString();
Your question is a little unclear, but it sounds like you want to be able to convert integers 0-25 to their corresponding alphabetical characters. If that's the case, your best bet logically is probably to use an enum. Though I may not be fully seeing the purpose of what you're trying to do (which is likely).
You could also write a utility method which just has a big switch statement to convert them.
An alternate method, for some java library flavor:
int value;
String output = Integer.toString(value + 10, 36);
which uses a radix of 36 to locate the right letter.

Categories