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 <willhart...@gmail.com> 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.999999% 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
<https://www.smashwords.com/profile/view/AlonsoDelarte>
Musician at ReverbNation.com <http://www.reverbnation.com/alonsodelarte>

Reply via email to