Java -- char[] to string - problem

Heyo guys,

There is a slight problem I encountered a few hours ago.

I have a char array and a string. If you put together the values of the different indexes of the array you'll get the exact same as the string.

There is a problem though, whenever I do that and compare those two , they apparently are NOT the same. I don't understand it.

If someone could explain this to me I would be very grateful.

Here is the sample code I setup, I don't want to bother you with my main program I'm writing, this snippet of code just highlights the problem:

 

char[] c = {'H', 'E', 'Y'};


String s = "HEY";



String cs = new String(c);



if(s == cs){


    System.out.println("true"); }

 

 

 

How do I correctly implement code? The <code> tags apparently don't work for me ..

You want s.equals(cs) instead of ==. The == operator compares the objects. Since cs and s are different objects, the comparison is false. String.equals() does a string comparison.

 Documentation.

 

Yup. The == is more for numeric values. Try the equals() method. Or in this case equalsIgnoreCase() would be more appropriate. 

The reason why these are not equal is because you are performing an equality test against the objects themselves.  This is false because these are two different objects and the equality operator is telling you s and cs are not the same object.

However, you can use the == operator to compare equality of string literal values.  E.g. String x = "My String";  

In Java, string literals are interned, so only one copy of a unique string literal value can exist within a a running Java JVM.

Likewise, if you create a string reference and assign it to an existing string value, you can use the == operator to compare equality.  E.g., String y = x;

In this case x and y are equal because they reference the same object.

Another important thing to remember with regards to using the equal method for Objects you create yourself is that by default the equals method you inherit from Object will use object identity for comparison, meaning it will return false if the objects being compared are different objects.  If you want to use instance variables within a given object to determine equality, you must override the equals method of your object.  And you must also override the hashCode method.  Two Objects' hash code must be the same if they are equal.  If you use an IDE like NetBeans or Eclipse, you can override equals and hashCode with a couple of mouse clicks.

See my below example for more details about String equality in Java:

String a = "test";

String b = "test";

System.out.println(a==b); //This will print true same String literal

String c = b;

System.out.println(b==c); //This will print true same String literal

//NEVER, NEVER use String's String construct to make Strings, 

//it creates unnecessary objects which can cause resources issues

String d = new String("test");

System.out.println(a==d); //This will print false different String Object

String e = d;

System.out.println(e==d); //This will print true same String Object

// Again, NEVER, NEVER use String's String construct to make Strings,


//it creates unnecessary objects which can cause resources issues

String f = new String(d);


System.out.println(f==d); //This will print false different String Object

 

Thank you lord for your excellent explanation.

There's one thing I would like to ask you though. What do you mean with "String's String construct"? Do you mean this :

String f = new String(d); 

?

Thank you

I think he's trying to say that you don't want to use the "String x = new String(y);". it's pointless in the first place, and, if I understand correctly, creates unneeded objects that take up extra memory.

if you're dealing with primitives, you don't ever need to use "new". rather, just do

   String x = y;

you only need to use "new" when creating a non-primitive object, like an ArrayList or custom object. I think Arrays are a little bit different, but whatever. 

EX:

    ArrayList<String> x = new ArrayList<String>();

or

   String[] X = new String[];       (for an array)

for objects, when you declare them like this, you are calling a constructor method, that creates a new object, that contains (in reality, points to the memory addresses of) primitives or objects of the datatype specified in the <>.

primitives don't need a constructor to be called, as primitives are directly translatable to binary. Strings are special, they are not primitives, but the String class in java allows them to be used as such.

so, when you use "String x = new String(y)", you would be creating a whole new set of chars with their own memory allocations. using "String x = y" just creates a new pointer to the preexisting memory allocations. this all works because the pointers can't be changed, instead, new pointers are created. it's all a creative illusion, more or less, as the memory objects are never really changed, only the pointers.

 

TL;DR:

in any case, you want to use .equals rather than == because == will only return true if both objects point to the same memory address, whereas .equals compares the actual value of the objects. generally, I only use == for int, boolean, and char.

 

see

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

and

https://stackoverflow.com/questions/7520432/java-vs-equals-confusion

There's no need to use the String constructor since you can equate it to a String literal or pre-existing String object instead

Instead of:

String name = new String("Thomas");

String nameCopy = new String(name);

Use:

String name = "Thomas";

String nameCopy = name;

Sorry for the delay in responding, I had a deadline at work.

The other posters pretty much answered your question. You always want to avoid making unnecessary objects whenever possible. This will use additional resources and potentially cause performance issues--you will end up using more heap memory and possibly cause the Garbage Collector to run more frequently.


This is especially the case with strings because of another property strings have in Java. In Java, strings are immutable, meaning whenever you create a new String that String can never be changed for its lifetime within the JVM. If you use any of the String mutator methods (e.g., myString.concat("add to end of string") ) on a String, you do not change the String value, a new String with the new value is created. This means that there is never a need to have more than one String object with the same value in a single, running JVM. If you have two String references pointing to the same String value and one reference executes a mutator method against the String, the original String's value will not be changed that reference will get a reference to a new String Object.

See the example below:



String x = "test2";


String y = x;


System.out.println(x==y); //This will print true same String Object


y = y.concat("again");


System.out.println(x==y); //This will print false x and y now reference different String Objects

And as a side note NEVER use String's concatenation methods to perform string manipulations. As I mentioned above, every time you use these methods new String Objects are created. You can take a big performance hit and chew up resources very quickly if your call to String's concatenations methods are done in a loop or in a method that is called very frequently.

One final comment about strings in Java, is that one of the main reasons why you would want to use == instead of myString.equals() is that using the == operator is much faster. If you are in a situation where you need very fast String comparisons, you can intern all of your String values, then you can use == to compare any String value. But you would have to be very diligent and make sure all your String values have been intern; otherwise, this would not work correctly.

Using the example from my previous post:


String a = "test";



String d = new String("test");



d=d.intern();



System.out.println(a==d); //This will print true a and d now reference the same String Object

Thank you! Very good.

Thank you for this very well explained answer.

Btw, how did you get the code tags working (if it are code tags)? Whenever I try to use code tags it will just come out as normal text.

I did use code tags.  This html interpreter is not very good.  It does not seem to format the text correctly.  I had to surround each line of code with < code >  < / code > and a < p / >  between each line of code--of course without the spaces between the word code and p, and the greater than and less than signs.

 

Aha. Well, that's a lot of work to just get your code in a post. haha