This page is no longer maintained — Please continue to the home page at www.scala-lang.org

eq method on String versus new String

5 replies
Alex Wouda
Joined: 2011-06-28,
User offline. Last seen 42 years 45 weeks ago.

Hi,

I understand that the 'eq' method checks for the same identity opposed
to == (equals) for equality. However looking at the following I don't
get it.

scala> val s1 = "test"
s1: java.lang.String = test

scala> val s2 = "test"
s2: java.lang.String = test

scala> s1 eq s2
res0: Boolean = true

scala> val s3 = new String("test")
s3: java.lang.String = test

scala> val s4 = new String("test")
s4: java.lang.String = test

scala> s3 eq s4
res1: Boolean = false

s1 and s2 get the same identity, s3 and s4 created with "new" are (as
expected) not equal in identity. I would expected s1 and s2 are
different variables pointing to the same value.

Why is is the result of 's1 eq s2' true?

regards,

Alex

marius
Joined: 2008-08-31,
User offline. Last seen 3 years 19 weeks ago.
Re: eq method on String versus new String
Because String literals are interned thus there is a single instance of string "test".

Marius

On Thu, Jun 23, 2011 at 11:11 AM, Alex Wouda <awouda@gmail.com> wrote:
Hi,

I understand that the 'eq' method checks for the same identity opposed
to == (equals) for equality. However looking at the following I don't
get it.

scala> val s1 = "test"
s1: java.lang.String = test

scala> val s2 = "test"
s2: java.lang.String = test

scala> s1 eq s2
res0: Boolean = true

scala> val s3 = new String("test")
s3: java.lang.String = test

scala> val s4 = new String("test")
s4: java.lang.String = test

scala> s3 eq s4
res1: Boolean = false

s1 and s2 get the same identity, s3 and s4 created with "new" are (as
expected) not equal in identity. I would expected s1 and s2 are
different variables pointing to the same value.

Why is is the result of 's1 eq s2'  true?

regards,

Alex

Philippe Lhoste
Joined: 2010-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: eq method on String versus new String

On 23/06/2011 10:11, Alex Wouda wrote:
> s1 and s2 get the same identity, s3 and s4 created with "new" are (as
> expected) not equal in identity. I would expected s1 and s2 are
> different variables pointing to the same value.
>
> Why is is the result of 's1 eq s2' true?

As explained in the two threads, it is a behavior of the JVM itself, ie. something I
learned when doing Java: constants like this, at least if they belong to the same class,
are automatically collapsed (interned) to the same address, as an attempt to optimize some
space. After all, strings are immutable, so there is no problem with that.

If you do s = new String("stuff"), which is generally seen as bad practice (redundant,
and, as you saw, defeating the interning behavior, which is rarely if ever needed), you
wrap these objects in a fresh new object, probably holding a reference to the interned
string itself.
Hence the different references.

Side note: when you use substring() (in Java, but I guess the behavior is the same in
Scala), you create a reference to the original string, you don't create a new string.
Which can be problematic if you keep a small substring of a large string (eg. the content
of an XML file) which would like to see garbage collected...

Ken McDonald
Joined: 2011-02-13,
User offline. Last seen 42 years 45 weeks ago.
Re: eq method on String versus new String

Side note: when you use substring() (in Java, but I guess the behavior is the same in
Scala), you create a reference to the original string, you don't create a new string.
Which can be problematic if you keep a small substring of a large string (eg. the content
of an XML file) which would like to see garbage collected...


Hmm, that comes as a bit of a shocker. I wonder if the same holds for substrings extracted from regexes, because it's certainly not uncommon to run regexes on some _really_ large strings.
Ken 
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: eq method on String versus new String

On Wed, Jun 29, 2011 at 18:50, Ken McDonald wrote:
>> Side note: when you use substring() (in Java, but I guess the behavior is
>> the same in
>> Scala), you create a reference to the original string, you don't create a
>> new string.
>> Which can be problematic if you keep a small substring of a large string
>> (eg. the content
>> of an XML file) which would like to see garbage collected...
>
> Hmm, that comes as a bit of a shocker. I wonder if the same holds for
> substrings extracted from regexes, because it's certainly not uncommon to
> run regexes on some _really_ large strings.

Quite likely, actually.

Danielk
Joined: 2009-06-08,
User offline. Last seen 3 years 21 weeks ago.
Re: Re: eq method on String versus new String
On Wed, Jun 29, 2011 at 11:50 PM, Ken McDonald <ykkenmcd@gmail.com> wrote:

Side note: when you use substring() (in Java, but I guess the behavior is the same in
Scala), you create a reference to the original string, you don't create a new string.
Which can be problematic if you keep a small substring of a large string (eg. the content
of an XML file) which would like to see garbage collected...


Hmm, that comes as a bit of a shocker. I wonder if the same holds for substrings extracted from regexes, because it's certainly not uncommon to run regexes on some _really_ large strings.
Ken 

Matcher#group uses CharSequence.subSequence. For Strings this does indeed mean that you get a substring that references the full char[]. If you're extracting small parts of a large Strings this is bad. Obviously you can work around this like so: String independent = new String (extractedSubstring);

Daniel

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland