Is it safe to use ==/!=
while comparing Character
?
Character being a boxed type is it safe to use ==/!=
while comparing Character types?
public static void main(String[] args) {
Character c1 = 'd';
Character c2 = (char) getInt();
System.out.println(c1 == c2);
}
public static int getInt() {
return 100;
}
The following works as expected (true). However, are there cases where comparing Character with same value using ==
would lead to false? (Hence, do we have to use '.equals()' while comparing boxed primitive types?
No, it's not safe. You must use equals()
.
Demonstration:
System.out.println(Character.valueOf('Ü') == Character.valueOf('Ü'));
// -> false
Note that if you use autoboxing or Character.valueOf()
, then some characters (ASCII characters) are cached and the same Character
instance is reused, so ==
may return true
for the same value:
System.out.println(Character.valueOf('A') == Character.valueOf('A'));
// -> true (on my machine)
But it doesn't work for all characters, and it won't work if you call the deprecated new Character(...)
explicitly.
Use code points, not char
/Character
.
"d".codePointAt( 0 ) == 100 // true.
The Answer by Alex Shesterov is correct. But bigger picture, you should not be using Character
objects.
Character
is brokenThe Character
class is a wrapper class for the primitive type char
. The char
/Character
type is legacy as of Java 2, and is essentially broken. As a 16-bit value, it is physically incapable of representing most characters.
For example, try running:
System.out.println( Character.valueOf( '😷' ) ) ;
Instead, when working with individual characters, use code point integer numbers. In Java that means using the int
/Integer
type.
If you look around classes such as String
, StringBuilder
, and Character
you will find codePoint
methods.
Let's revise your code snippet. We will change the names to be more descriptive. We switch out Character
and char
usage for mere int
primitive integers. As such, we can compare our int
values using ==
or !=
.
package work.basil.text;
public class App7
{
public static void main ( String[] args )
{
int codePointOf_LATIN_SMALL_LETTER_D = "d".codePointAt( 0 ); // Annoying zero-based index counting, not ordinal.
int codePoint2 = getInt();
boolean sameCharacter = ( codePointOf_LATIN_SMALL_LETTER_D == codePoint2 ); // Comparing `int` primitives with double-equals.
System.out.println( sameCharacter );
}
public static int getInt ()
{
return 100; // Code point 100 is LATIN SMALL LETTER D, `d`.
}
}
When run:
true
Of course, if you use auto-boxing or otherwise mix the wrapper class Integer
with the primitive int
, then the same explanation in that other Answer applies here too.
Integer
object to Integer
object by calling Integer#equals
or Objects.equals( Object a , Object b )
rather than using ==
.int
primitive to int
primitive using ==
or calling Integer.compare( int x , int y )
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With