Re: Re: hashCode: same every run?

2021-05-08 Thread Eric Bresie


Maybe can check each hashCode to see how they calculate it

https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Object.java

https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/String.java

Eric Bresie
ebre...@gmail.com (mailto:ebre...@gmail.com)

> On May 6, 2021 at 12:49:30 PM CDT, Eduard  (mailto:i...@dejongfrz.nl)> wrote:
> You are computing the hash on a compile time constant value, so that value is 
> itself a compile tiem constant, and can be deived from the memory location 
> where that constant gets allocated when the JVM starts up. This works for 
> strings as they are all internalized at compile time, that is stored in a 
> common table that holds a unique copy of each String, that way the storage 
> location corresponds with the content of the String, and so does the hash 
> value.
>
> If you look at the code for String.java, you will see it actually computes 
> the hash value based on the characters it contains. This only is used on 
> strings you create while your code is running.
>
> --
> Eduard
>
> Shaun Flynn wrote on 06/05/2021 17:22 (x-apple-data-detectors://4):
> > I ran into this, thinking it would be the same per execution, but it does 
> > not work like that.
> >
> > If you create a for loop doing something like...
> >
> > String test = "Hello World!";
> > for(i = 0; i < 100; i++) {
> > System.out.println(test.hashCode());
> > }
> >
> > You will get 100 identical values.
> >
> > Run it again, you will get 100 values identical values again, but the value 
> > has changed.
> >
> > Ie first run prints "46521890 (tel:46521890)" 100 times
> > Second run prints "-56905325700" 100 times
> >
> > And each subsequent run with produce a different hashCode repeated 100 
> > times.
> >
> > I believe (feel free to correct me) that the algorithm or formula for 
> > producing ths hashCode has the memory address as an input, thus it will 
> > different per execution because the JVM allocates the memory, which has the 
> > effect of appearing random.
> >
> > It confused me at first, but this is the intended functionality: if you are 
> > intending to store hashes for lookup or other purposes, use one of the 
> > already defined hash functions eg 
> > https://www.geeksforgeeks.org/sha-256-hash-in-java/
> >
> > Hope this helps.
> >
> > Shaun
> > On Thu, 6 May 2021, 13:46 Charles Johnson,  > (mailto:cehjohn...@gmail.com)> wrote:
> > > On 06/05/2021 12:37 (x-apple-data-detectors://9), Christopher C. Lanz 
> > > wrote:
> > > > It would be helpful if I could rely on hashCode always to return the 
> > > > same integer for the same object.
> > >
> > > What are you doing such that needs to be the case?
> > >
> > >
> > >
> > > CJ
> > >
> > >
> > >
> >
> >
>
>


Re: hashCode: same every run?

2021-05-06 Thread Eduard
You are computing the hash on a compile time constant value, so that 
value is itself a compile tiem constant, and can be deived from the 
memory location where that constant gets allocated when the JVM starts 
up. This works for strings as they are all internalized at compile time, 
that is stored in a  common table that holds a unique copy of each 
String, that way the storage location corresponds with the content of 
the String, and so does the hash value.


If you look at the code for String.java, you will see it actually 
computes the hash value based on the characters it contains. This only 
is used on strings you create while your code is running.


--
Eduard

Shaun Flynn wrote on 06/05/2021 17:22:
I ran into this, thinking it would be the same per execution, but it 
does not work like that.


If you create a for loop doing something like...

String test = "Hello World!";
for(i = 0; i < 100; i++) {
System.out.println(test.hashCode());
}

You will get 100 identical values.

Run it again, you will get 100 values identical values again, but the 
value has changed.


Ie first run prints "46521890" 100 times
Second run prints "-56905325700" 100 times

And each subsequent run with produce a different hashCode repeated 100 
times.


I believe (feel free to correct me) that the algorithm or formula for 
producing ths hashCode has the memory address as an input, thus it 
will different per execution because the JVM allocates the memory, 
which has the effect of appearing random.


It confused me at first, but this is the intended functionality: if 
you are intending to store hashes for lookup or other purposes, use 
one of the already defined hash functions eg 
https://www.geeksforgeeks.org/sha-256-hash-in-java/


Hope this helps.

Shaun

On Thu, 6 May 2021, 13:46 Charles Johnson, > wrote:


On 06/05/2021 12:37, Christopher C. Lanz wrote:

It would be helpful if I could rely on hashCode*always* to return
the same integer for the same object. 


What are you doing such that needs to be the case?

CJ





Re: hashCode: same every run?

2021-05-06 Thread Alonso Del Arte
It shouldn't change, String is supposed to be an immutable class. At least
for Oracle JDK 8, hash codes for String instances are based on a recurrence
relation on the Unicode character values, *a*(*n*) = 31*a*(*n* − 1) + char.
So if a String only contains a single character, its hash code should be
the same as the equivalent Character instance.

C:\Users\AL>scala
Welcome to Scala 2.13.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_291).
Type in expressions for evaluation. Or try :help.

scala> "a".hashCode
res0: Int = 97

scala> 'a'.hashCode
res1: Int = 97

scala> 97 * 31 + 32
res2: Int = 3039

scala> "a ".hashCode
res3: Int = 3039

It shouldn't make a difference whether hashCode() is being invoked from
NetBeans running a JUnit test suite, from the Scala REPL, or any other
execution context that might be possible on your system.

However, for a class with the default hashCode() from Object, the execution
context might make a big difference. It seems to me that when running
JUnit, higher hash codes are assigned in IntelliJ than in NetBeans. But
that's an unscientific observation.

Al

On Thu, May 6, 2021 at 1:01 PM Will Hartung  wrote:

> That loophole about different values from run to run is solely for the
> default implementation of hashcode, which is based on the actual internal
> implementation of the instance.
>
> Consider:
>
> class MyClass {
>
> int val = 1;
>
> public MyClass() {
> }
> }
>
> MyClass c1 = new MyClass();
> MyClass c2 = new MyClass();
>
> System.out.println("c1 hc = " + c1.hashCode());
> System.out.println("c2 hc = " + c2.hashCode());
> System.out.println("c1 == c2 " + (c1 == c2));
> System.out.println("c1 eq c2 " + (c1.equals(c2)));
>
> c1 hc = 401424608
> c2 hc = 2101440631
> c1 == c2 false
> c1 eq c2 false
>
> By most accounts, these two instances (c1 and c2) are "equal". They both
> have the same internal state (but are not the same object, == fails as it
> should). But the default JVM equals implementation does not check the
> internal state of the object.
>
> As long as this process is running, c1 will retain it's hash code, and so
> will c2. But if you run it again, there is no guarantee that these values
> will be the same, just consistent within the specific executable.
>
> But, this is not how hashCode and equals are implemented in the real
> world. By default the JVM does not "properly" implement hashCode and
> equals. I mean, arguably, it's accurate: here are two instances that not
> not "equal", thus they don't have the same hash code. By that aspect of the
> contract, it's fine. It's just not very useful, and thus requires all
> classes having to implement their own versions of equals and hashCode.
>
> Since the classes inevitably dictate the behavior of equals and hashCode,
> they can "guarantee" that the values returned transcend the execution state.
>
> You can analyze the hashCode implementation for String and discern whether
> the value may change from run to run (it won't, but you can at least
> check). You can discern this from any class that implements equals and
> hashCode. So, for 99.99% of the use cases of hashCode, changing values
> from run to run is not an issue, and is under the developers control. The
> docs simply say it can because the default implementations of hashCode do
> that. The default implementation of hashCode isn't particularly useful for
> most use cases.
>
> Regards,
>
> Will Hartung
>
>

-- 
Alonso del Arte
Author at SmashWords.com

Musician at ReverbNation.com 


Re: hashCode: same every run?

2021-05-06 Thread Will Hartung
That loophole about different values from run to run is solely for the
default implementation of hashcode, which is based on the actual internal
implementation of the instance.

Consider:

class MyClass {

int val = 1;

public MyClass() {
}
}

MyClass c1 = new MyClass();
MyClass c2 = new MyClass();

System.out.println("c1 hc = " + c1.hashCode());
System.out.println("c2 hc = " + c2.hashCode());
System.out.println("c1 == c2 " + (c1 == c2));
System.out.println("c1 eq c2 " + (c1.equals(c2)));

c1 hc = 401424608
c2 hc = 2101440631
c1 == c2 false
c1 eq c2 false

By most accounts, these two instances (c1 and c2) are "equal". They both
have the same internal state (but are not the same object, == fails as it
should). But the default JVM equals implementation does not check the
internal state of the object.

As long as this process is running, c1 will retain it's hash code, and so
will c2. But if you run it again, there is no guarantee that these values
will be the same, just consistent within the specific executable.

But, this is not how hashCode and equals are implemented in the real world.
By default the JVM does not "properly" implement hashCode and equals. I
mean, arguably, it's accurate: here are two instances that not not "equal",
thus they don't have the same hash code. By that aspect of the contract,
it's fine. It's just not very useful, and thus requires all classes having
to implement their own versions of equals and hashCode.

Since the classes inevitably dictate the behavior of equals and hashCode,
they can "guarantee" that the values returned transcend the execution state.

You can analyze the hashCode implementation for String and discern whether
the value may change from run to run (it won't, but you can at least
check). You can discern this from any class that implements equals and
hashCode. So, for 99.99% of the use cases of hashCode, changing values
from run to run is not an issue, and is under the developers control. The
docs simply say it can because the default implementations of hashCode do
that. The default implementation of hashCode isn't particularly useful for
most use cases.

Regards,

Will Hartung


Re: hashCode: same every run?

2021-05-06 Thread Shaun Flynn
I ran into this, thinking it would be the same per execution, but it does
not work like that.

If you create a for loop doing something like...

String test = "Hello World!";
for(i = 0; i < 100; i++) {
System.out.println(test.hashCode());
}

You will get 100 identical values.

Run it again, you will get 100 values identical values again, but the value
has changed.

Ie first run prints "46521890" 100 times
Second run prints "-56905325700" 100 times

And each subsequent run with produce a different hashCode repeated 100
times.

I believe (feel free to correct me) that the algorithm or formula for
producing ths hashCode has the memory address as an input, thus it will
different per execution because the JVM allocates the memory, which has the
effect of appearing random.

It confused me at first, but this is the intended functionality: if you are
intending to store hashes for lookup or other purposes, use one of the
already defined hash functions eg
https://www.geeksforgeeks.org/sha-256-hash-in-java/

Hope this helps.

Shaun

On Thu, 6 May 2021, 13:46 Charles Johnson,  wrote:

> On 06/05/2021 12:37, Christopher C. Lanz wrote:
>
> It would be helpful if I could rely on hashCode* always* to return the
> same integer for the same object.
>
> What are you doing such that needs to be the case?
>
> CJ
>


Re: hashCode: same every run?

2021-05-06 Thread Christian Pervoelz
State of now, the hashCode of a String is the same in between different
executions for (most) oracle vms.
That might change in the future and might not be correct for all vms out
there.

If you you want to go sure and be future safe, the only valid way I see, is
to create a utility method created in a class controlled by you, which will
return a stable int for a given string each time you invoke it.

Java itself cannot promise such a behavior, as an object created in one
execution is *NOT *the same as the object of another execution. Even not
for strings.

Am Do., 6. Mai 2021 um 13:38 Uhr schrieb Christopher C. Lanz
:

> Hello,
>
> Oracle's documentation for hashCode asserts:
>
> *Whenever it is invoked on the same object more than once during an
> execution of a Java application, the hashCode method must consistently
> return the same integer, provided no information used in equals comparisons
> on the object is modified. This integer need not remain consistent from one
> execution of an application to another execution of the same application. *
>
> It would be helpful if I could rely on hashCode* always* to return the
> same integer for the same object.
>
> The documentation implies that I cannot rely on the function in this way.
> I have tested it several times, and the same integers are returned every
> time, between separate runs of the application, after exiting and
> restarting NetBeans, and after rebooting the computer. But it's not
> possible to do hundreds of tests, so I'm asking if anyone knows enough
> about this method to say that it will always return consistent values.
>
> Here is the code I used for testing (I am only concerned with calls to
> hashCode on Strings):
>
> public static void main(String[] args) {
>
>String s1 = "asddh:2 qwert:3 zxcv:4";
>String s2 = "poiuy:19 lkjhg:22  mnbvc:27 jghfkd:16";
>String s3 = "lakdnofgneoqwinelkvnlzjkndoafoibvklaznbdslvnvlaksv";
>
>System.out.println(s1.hashCode()+"  "+s2.hashCode()+"
>  "+s3.hashCode());
>
> }
>
> Thanks very much.
>
>
> Chris Lanz
>
> Department of Computer Science
>
> 340 Dunn Hall, SUNY Potsdam
>
> lan...@potsdam.edu
> 315 268 1547
>
>
>
>
>


Re: hashCode: same every run?

2021-05-06 Thread Charles Johnson

On 06/05/2021 12:37, Christopher C. Lanz wrote:
It would be helpful if I could rely on hashCode*always* to return the 
same integer for the same object. 


What are you doing such that needs to be the case?

CJ



hashCode: same every run?

2021-05-06 Thread Christopher C. Lanz
Hello,

Oracle's documentation for hashCode asserts:

Whenever it is invoked on the same object more than once during an execution of 
a Java application, the hashCode method must consistently return the same 
integer, provided no information used in equals comparisons on the object is 
modified. This integer need not remain consistent from one execution of an 
application to another execution of the same application.

It would be helpful if I could rely on hashCode always to return the same 
integer for the same object.

The documentation implies that I cannot rely on the function in this way. I 
have tested it several times, and the same integers are returned every time, 
between separate runs of the application, after exiting and restarting 
NetBeans, and after rebooting the computer. But it's not possible to do 
hundreds of tests, so I'm asking if anyone knows enough about this method to 
say that it will always return consistent values.

Here is the code I used for testing (I am only concerned with calls to hashCode 
on Strings):

public static void main(String[] args) {

   String s1 = "asddh:2 qwert:3 zxcv:4";
   String s2 = "poiuy:19 lkjhg:22  mnbvc:27 jghfkd:16";
   String s3 = "lakdnofgneoqwinelkvnlzjkndoafoibvklaznbdslvnvlaksv";

   System.out.println(s1.hashCode()+"  "+s2.hashCode()+"  "+s3.hashCode());

}

Thanks very much.


Chris Lanz

Department of Computer Science

340 Dunn Hall, SUNY Potsdam

lan...@potsdam.edu

315 268 1547