Hashcode value is same - java

why hashcode value is same?
public static void main(String args[])
{
String s1="abc";
String s2=new String("abc");
System.out.println("Hashcode s1-:"+ s1.hashCode());
System.out.println("Hashcode s2-:"+ s2.hashCode());
if(s1==s2){
System.out.println("==true:");
}
}
output
Hashcode s1-:96354
Hashcode s2-:96354

The hash code for two equal objects should be equal.
In this case, the objects are strings and they are considered equal because they hold the same sequence of characters, "abc".
If you want a hash code that is based on object identity rather than equality use System.identityHashCode().

Why wouldn't they be the same? The hashcode is computed on the contents of the string, hence they are the same for both.
== compares object references, and because you used new String for s2 the references are not the same.
You should be using the equals method to test equality of strings based on their value.

Because the hashcode is computed using the formula which takes in only the characters present in the string. Same characters in a String will yield the same hashcode.
Javadoc for the computation formula.

This is because of how the hashcode of String are computed in java.
Check the javadoc : http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
And more over, your two strings are equals, therefore their hashcode must be the same.

This is the code...therefore the result is the same for two equals objects:
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}

as per the rules, objects for those equals method return true, should have the same hashcode.

Hashcode for a string is computed based on its characters and so is equals()
It is calculated as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
where s[i] is each character for 0<=i<n and n is its length.
Both your strings have the same content and thus hashcode is the same.

String class has its own hashcode method implemeted in it. Its method will compute the hashcode as: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
So for the same character sequence hashcode will be same.

The JVM doesn't create a new String if this already exist, it just returns the reference. A new String will be created when you try to change the actual String in one of the vars.
You can check it debugging the application, the String objects will have different memory addresses but the value inside will have exactly the same memory address.

Related

difference between creating java string with and without new operator [duplicate]

This question already has answers here:
What is the difference between strings allocated using new operator & without new operator in java J2ME?
(5 answers)
Closed 8 years ago.
With new operator String create the string in heap and put a copy in string const pool so the result of hashcode is same in below case;
String s1 = new String("Test");
String s2 = new String("Test");
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
But without using new operator its still giving the same hashcode
String s1 = new String("Test");
String s2 = "Test";
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
Then what is the differnce between above two notation of string creation although they are referening to same string in string const. pool
Based on Effective java.
It is often appropriate to reuse a single object instead of creating a
new function- ally equivalent object each time it is needed. Reuse can
be both faster and more stylish. An object can always be reused if it
is immutable. As an extreme example of what not to do,
consider this statement:
String s = new String("stringette"); // DON'T
DO THIS!
The statement creates a new String instance each time it is
executed, and none of those object creations is necessary. The
argument to the String construc- tor ( "stringette" ) is itself a
String instance, functionally identical to all of the objects created
by the constructor. If this usage occurs in a loop or in a frequently
invoked method, millions of String instances can be created
needlessly.
The improved version is simply the following:
String s = "stringette";
This version uses a single String instance, rather than creating a new
one each time it is executed. Furthermore, it is guaranteed that the
object will be reused by any other code running in the same virtual
machine that happens to con- tain the same string literal
therefore creating unnecessary new Object of String or any other Objects are expensive.
From docs and Java.lang.String class, Internal Implementation of hashCode()
/**
* Returns a hash code for this string. The hash code for a
* String object is computed as
*
* s[0]*31^(n-1) + s1*31^(n-2) + ... + s[n-1]
*
* using int arithmetic, where s[i] is the
* ith character of the string, n is the length of
* the string, and ^ indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* #return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
More about String hashcode here
Both expression gives you String object, but there is difference between them. When you create String object using new() operator, it always create a new object in heap memory. On the other hand, if you create object using String literal syntax e.g. String s2 = "Test"; it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists. Otherwise it will create a new string object and put in string pool for future re-use.
for further reading see:here
String str = new String("String");
always create a new object on the heap.
Here creates a new String having for value the value of the constant "String" and assignates its reference to the variable str.
String str = "String";
uses the String pool
Here assignates the reference associated to the constant "String" to the variable str

Java String pool Storage doubts [duplicate]

This question already has answers here:
Testing string equality using hashCode()
(10 answers)
Closed 9 years ago.
why hashcode are same of string object ???
I'm trying to understand how string pool works.I have gone through many sites and finally i'm more confused now. Let me put down my doubts here. Someone help me in understanding them.
class cov {
public static void main(String[] args) {
String s = "abc"; //Object on string pool
System.out.println(s.hashCode());
String str = new String("abc"); //This statement does two things
System.out.println(str.hashCode());
}
}
A String's hashCode() method is calculated based on the chars it contains. If two String objects contain the same chars with the same case and in the same order, then they will have the same hashCode().
The String class has a hashCode method that calculates the hash code from its content, not from its memory location. So if two strings are identical (but not necessarily equal), they will have the same hash code.
If this were not the case, a structure such as HashSet<String> would be unusable - every new String would turn out not to be in the set, even when a String with the same characters had already been added.
Below is the source code which is used for generating hashCode
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
And as described in other answers hashCode is generated from the contents of the String not the place where it is residing. e.g heap stack or constant pool

Compare two long Strings

I want to compare two string who have those form
s1="1390785186301"
s2="1390785191301"
Shall I convert them to long and then compare with > or there are methods?
Consider using this natural comparator, in case you are not sure, if there are digits only in your string.
The problem with using a string comparison is that in a string compare 12 comes before 9, not after it.
You will need to convert it to either a long (if it fits within the range of a 64 bit integer) or a BigInteger and then do the comparison using them.
For the long do:
if (Long.parseLong(str1) > Long.parseLong(str2)) {
}
or:
int comparison = Long.compare(Long.parseLong(str1), Long.parseLong(str2));
The final option would be to do your own string comparator which scans from the start of the string comparing one digit at a time but if the strings are not equal length treats the shorter one as though it was left padded with 0.
If you want to compare two strings, just use the compareTo method
if(s1.length() == s2.length()){
if(s1.compareTo(s2) > 0) {//then s1 is greater...}
}
Take a look at the javadoc
String#compareTo
Here full ans
public class Comparetion {
public static void main(String args[]){
String s1="1390785186301";
String s2="1390785191301";
if (s1.compareTo(s2) == 0) {
System.out.println("s1 and S2 its same");
}
if (s1.compareTo(s2) > 0) {
System.out.println("S1 is bigger then s2");
}
if (s1.compareTo(s2) < 0) {
System.out.println("S2 is less then S1");
}
}
}
public class Comparetion {
public static void main(String args[]){
String s1="1390785186301";
String s2="1390785191301";
if (Long.parseLong(s1) < Long.parseLong(s2)) {
System.out.println("s1 is less then s2");
}
else if(Long.parseLong(s1) > Long.parseLong(s2)){
System.out.println("s1 is bigger then s2");
}
else{
System.out.println("s1 and s2 are same.");
}
}
}
two possibilities. but in the case of Compare to will get exceptional cases.
if (new Long(s1) > new Long(s2))
// do your thing
I see no reason for not creating longs for this.
Here's more info: http://docs.oracle.com/javase/6/docs/api/java/lang/Long.html#Long%28java.lang.String%29
Depending on what you need you can check if both strings contains exactly same value with equals method (assuming no leading zeroes and that both numbers are represented using same notation, for instance "101" and "1.01E2" represent same value but strings are not equal).
But if you want to check which string contains bigger value String doesn't provide much help. It has its own compareTo method but it is using alphabetic order, which may fail if
strings are not same length: just like ab will be placed before b in dictionary, same rule applies to "12" "2" which means that 12 < 2 using this order
we are comparing negative values: example 12 < 13 in alphabetic order, but it also means -12 < -13.
It is much easier and safer to convert strings to proper numeric type like Long, BigInteger or even BigDecimal and use appropriate methods, like compareTo.
Demo
String s1 = "1390785186301";
String s2 = "1390785191301";
System.out.println(Long.compare(Long.parseLong(s1), Long.parseLong(s2))); // -1
System.out.println(new BigInteger(s1).compareTo(new BigInteger(s2))); // -1
negative value for a.compareTo(b) indicates that a<b, 0 that a==b, positive that a>b
Demo 2:
BigDecimal bigDecimal = new BigDecimal("101");
BigDecimal bigDecimal2 = new BigDecimal("1.01E2");
System.out.println(bigDecimal.equals(bigDecimal2)); // true
System.out.println(bigDecimal.compareTo(bigDecimal2)); // 0

Why does the equals method in String not use hash?

The code of the equals method in class String is
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
I have a question - why does this method not use hashCode() ?
As far as I know, hashCode() can compare two strings rapidly.
UPDATE: I know, that two unequal strings, can have same hashes. But two equal strings have equal hashes. So, by using hashCode(), we can immediately see that two strings are unequal.
I'm simply thinking that using hashCode() can be a good filter in equals.
UPDATE 2: Here some code, about we are talking here.
It is an example how String method equals can look like
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
if (hashCode() == anotherString.hashCode()){
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}else{
return false;
}
}
return false;
}
Hashcode could be a first-round check for inequality. However, it presents some tradeoffs.
String hashcodes are lazily calculated, although they do use a "guard" value. If you're comparing strings with long lifetimes (ie, they're likely to have had the hashcode computed), this isn't a problem. Otherwise, you're stuck with either computing the hashcode (potentially expensive) or ignoring the check when the hashcode hasn't been computed yet. If you have a lot of short-lived strings, you'll be ignoring the check more often than you'll be using it.
In the real world, most strings differ in their first few characters, so you won't save much by checking hashcode first. There are, of course, exceptions (such as URLs), but again, in real world programming they occur infrequently.
This question has actually been considered by the developers of the JDK. I could not find in the various messages why it has not been included. The enhancement is also listed in the bug database.
Namely, one of the proposed change is:
public boolean equals(Object anObject) {
if (this == anObject) // 1st check identitiy
return true;
if (anObject instanceof String) { // 2nd check type
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) { // 3rd check lengths
if (n != 0) { // 4th avoid loading registers from members if length == 0
int h1 = hash, h2 = anotherString.hash;
if (h1 != 0 && h2 != 0 && h1 != h2) // 5th check the hashes
return false;
There was also a discussion to use == for interned strings (i.e. if both strings are interned: if (this != anotherString) return false;).
1) Calculating hashCode may not be faster than comparing the Strings directly.
2) if the hashCode is equal, the Strings may still not be equal
This can be a good idea for many use cases.
However, as a foundation class that is widely used in all kinds of applications, the author really has no idea whether this extra checking can save or hurt performance on average.
I'm gonna guess that the majority of String.equals() are invoked in a Hashmap, after the hash codes has been known to be equal, so testing hash codes again is pointless.
If we consider comparing 2 random strings, even with a small char set like US ASCII, it is very likely that the hashes are different, and char-by-char comparison fails on 1st char. So it'll be a waste to check hashes.
AFAIK, The following check could be added to String. This check that if the hash codes are set and they are different, then the Strings cannot be equal.
if (hash != 0 && anotherString.hash != 0 && hash != anotherString.hash)
return false;
if (hash32 != 0 && anotherString.hash32 != 0 && hash32 != anotherString.hash32)
return false;
The string hash code is not available for free and automatically. In order to rely on hash code, it must be computed for both strings and only then can be compared. As collisions are possible, the second char-by-char comparison is required if the hash codes are equal.
While String appears as immutable for the usual programmer, it does have the private field to store its hashcode once it is computed. However this field is only computed when hashcode is first required. As you can see from the String source code here:
private int hash;
public int hashCode() {
int h = hash;
if (h == 0) {
...
hash = h;
}
return h;
}
Hence it is not obvious that it makes sense to compute the hashcode first. For your specific case (maybe same instances of really long strings are compared with each other a really many of times), it still may be: profile.
As I think, hashCode() can make comparison of two strings quicker.
Arguments?
Arguments against this proposal:
More Operations
hashcode() from String has to access every character in the String and has to do 2 calculations for every character.
So we need for a string with n characters 5*n operations (load, multiplication, lookup/load, multiplication, store). Two times, because we compare two Strings. (Ok, one store and one load does not really count in a reasonable implementation.)
For the best case, this makes a total of 10*x operations for two strings with length m and n and x=min(m,n). Worst case is 10*x with x=m=n. Average somewhere between, perhaps (m*n)/2.
The current equals implementation needs in the best case 3 operations. 2 loads, 1 compare. Worst is 3*x operations for two strings with length m and n and x=m=n. Average is somewhere between, perhaps 3*(m*n)/2.
Even if we cache the hash, it is not clear that we save something
We have to analyze usage patterns. It could be that most of the time, we will only ask one time for equals, not multiple times. Even if we ask multiple times, it could not be enough to have time savings from the caching.
Not direct against the speed, but still good counterarguments:
Counter intuitive
We do not expect a hashcode in equals, because we know for sure that hash(a)==hash(b) for some a!=b. Everyone reading this (and knowledge about hashing) will wonder what is happening there.
Leads to bad examples/unexpected behavior
I can already see the next question on SO: "I have a String with some billion times 'a'. Why does it take forever to compare it with equal() against 'b'?" :)
If the hash code takes the whole content of the string into account, then calculating the hash code of a string with n characters takes n operations. For long strings that's a lot. Comparing two strings takes n operations if they are the same, not longer than calculating the hash. But if the strings are different, then a difference is likely to be found a lot earlier.
String hash functions usually don't consider all characters for very long strings. In that case, if I compare two strings I could first compare the characters used by the hash function, and I'm at least as fast as checking the hashes. But if there is no difference in these characters, then the hash value will be the same, so I have to compare the full strings anyway.
Summary: A good string comparison is never slower but often a lot faster than comparing the hashes (and comparing strings when the hashes match).

Setting a variable to a value in if statement

static int findPerson(String n, int NP, Friend[] giftGivers){
int index = 0;
for (int i = 0; i < NP; i++){
if (giftGivers[i].name == n){
index = i;
}
}
return index;
}
I have this code in Java for a method to search through an array of Friends to find the index number of the person with the name input by String n. however i have found that the index number does not set to the index number it is should be. Is it because it is in the if statement?
if (giftGivers[i].name == n) is wrong, use if (giftGivers[i].name.equals(n))
BTW, there is no need to use NP. It's C-style, not necessary (actually, pretty dangerous) in Java. Instead of
for (int i = 0; i < NP; i++),
just say for (int i = 0; i < giftGivers.length; i++)
You need to use equals to compare strings not ==.
== will compare the object references rather than the actual string value.
If you don't care about case, then there is also an equals method that ignores case
(giftGivers[i].name == n){
should be
(giftGivers[i].name.equals(n)){
String/Object comparison should use .equals() instead of ==
== will check for reference equality. equals() check for object equality.
.equals() method checks for equality of two string objects, == operator checks if two refrence variables point to the same String object.
In your case you have to use .equals() method
if (giftGivers[i].name.equals(n))
refer to String API.
Note that if you wanna check if two strings are equal case insensitive use equalsIgnoreCase()

Categories