Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (808)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (872)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Check if ArrayList Contains String  (Read 9251 times)
0 Members and 1 Guest are viewing this topic.
Offline Rayexar
« Posted 2015-02-04 10:23:40 »

I know this sounds really simple and it should be, but I can't figure out what the problem is.

I have an ArrayList of strings, such that the 627th element is "
1  
AESTHETICS
" exactly as printed out on the console (using
1  
arraylist.get(627)
).

When I use arraylist.contains("AESTHETICS"), it returns false. Using this method, it also returns false:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
boolean dictContains(String s) {
      for(String str: arraylist) {
         if(str.equalsIgnoreCase(s)) {
            return true;
         }
      }
     
      return false;
     
   }


Can someone please point out what the problem is?
Offline SHC
« Reply #1 - Posted 2015-02-04 10:37:57 »

Strings are immutable, when you are doing "AESTHETICS", the JVM is creating a new String object. You have to iterate all the objects in the list, and check using the
equals
method.

1  
2  
3  
boolean contains = false;

arraylist.forEach((s) -> contains = contains || s.equals("AESTHETICS"));

That should solve the problem.

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #2 - Posted 2015-02-04 10:49:07 »

SHC: you're severely misinformed Pointing

1  
2  
3  
4  
5  
6  
7  
8  
9  
      List<String> dict = new ArrayList<>();

      dict.add("WURD");
      dict.add("WORD");
      dict.add("AESTHETICS");
      dict.add("WERD");

      System.out.println(dict.contains("AESTHETICS")); // returns true
      System.out.println(dict.contains(new String("AESTHETICS"))); // returns true

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline SHC
« Reply #3 - Posted 2015-02-04 11:01:36 »

Oh my, that was true. I just thought that it is because strings are immutable. Could you also please explain why it was not working in the OP's code? I think he is also doing the same.

I'm completely stumped now..  Clueless Huh

Offline Rayexar
« Reply #4 - Posted 2015-02-04 11:01:50 »

Hey, thanks for the replies

I still don't understand how to fix it though, because I thought I was already checking using equals (equalsIgnoreCase). Can you please explain?
Offline ags1

JGO Kernel


Medals: 367
Projects: 7


Make code not war!


« Reply #5 - Posted 2015-02-04 11:14:34 »

Perhaps the string is actually "AESTHETICS ", ie includes whitespace. Print to console including quotes to see this. Or its "AESTHETICS\r" resulting from splitting a windows text file by '\n'.

Offline Rayexar
« Reply #6 - Posted 2015-02-04 11:25:38 »

That was a good idea, turns out there was a new line at the end of the word. Printing with quotes gave
1  
2  
"AESTHETICS
"


Thank you all Smiley
Offline Roquen

JGO Kernel


Medals: 518



« Reply #7 - Posted 2015-02-04 13:10:38 »

All strings in the constant pool of a class file, which include all explictly defined strings are (currently) interned at class resolution time.  So currently the reference will return true for == thoughout a VM.  This was a really bad idea and they're thinking of making it go away.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #8 - Posted 2015-02-04 13:25:13 »

All strings in the constant pool of a class file, which include all explictly defined strings are (currently) interned at class resolution time.  So currently the reference will return true for == thoughout a VM.  This was a really bad idea and they're thinking of making it go away.

This is highly confusing, given that Oracle just added String deduplication to the JVM. It pretty much acts like a GC, scanning the heap for duplicate Strings, rewriting references in case it found duplicates, so that after a while,
1  
2  
3  
4  
5  
6  
String s1 = new String("abc");
String s2 = new String("abc");
while(s1 != s2) {
   continue;
}
System.out.println("deduplicated");
will break from the loop.

If explicitly defined Strings are no longer a single 'interned' String anymore (AKA duplication), the deduplication feature will make them a single String after a while anyway.

On a side note: I believed that in recent Oracle JVMs the concept of 'interned' is deprecated/void anyway, which was possible due to the aforementioned deduplication feature.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline KevinWorkman

« JGO Plugged Duke »


Medals: 288
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #9 - Posted 2015-02-04 16:16:36 »

Are you sure that's how deduplication works?

I thought that the only thing that was overwritten was the private char array inside a String instance.

So the String instances would still be !=, it's just that their char arrays would be ==.

(source)

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2015-02-04 16:34:14 »

Hm. Hm.

Well, once Strings and their char[]s are fused (future JREs) my point would stand Emo

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #11 - Posted 2015-02-04 16:36:19 »

The loop WILL terminate, just maybe not for the next half decade...
Offline Gibbo3771

JGO Kernel


Medals: 128
Projects: 5
Exp: 1 year


Currently inactive on forums :(


« Reply #12 - Posted 2015-02-04 17:18:49 »

I am a little confused here.

Is the OP checking to see if a given instance of String is inside the array? or if there is a String inside the array that has the same character sequence?

If the latter could you not just check if String A has the same character sequence as String B and ignore all case?

Is that what this does?:


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
boolean dictContains(String s) {
      for(String str: arraylist) {
         if(str.equalsIgnoreCase(s)) {
            return true;
         }
      }
     
      return false;
     
   }


Or is this actually calling .equals inside the method after lowering the case of the given string? Not sure what is happening here :S.

"This code works flawlessly first time and exactly how I wanted it"
Said no programmer ever
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #13 - Posted 2015-02-04 17:22:09 »

He's checking for the existence of the same character sequence, disregarding case. The code is correct, but his data wasn't trim()'d and had trailing whitespace that he didn't notice.
Offline Roquen

JGO Kernel


Medals: 518



« Reply #14 - Posted 2015-02-05 10:39:34 »

This is highly confusing, given that Oracle just added String deduplication to the JVM. It pretty much acts like a GC, scanning the heap for duplicate Strings, rewriting references in case it found duplicates, so that after a while,
1  
2  
3  
4  
5  
6  
String s1 = new String("abc");
String s2 = new String("abc");
while(s1 != s2) {
   continue;
}
System.out.println("deduplicated");


Different issue. "abc" is a single instance in the constant pool.  If another class also has "abc" in it they will (currently) be interned and have identical references.  The code above is explicitly making two duplicates via new.  So we now have (at least) three copies on heap.  The deduplication feature will (at some point) reduce the number.

While we're talking about this...one big problem with string identity is that it's part of the spec and because of that some large corp codebases have "clever" constructions like:
synchronized("abc")
but then again,
new String("abc")
is equally clever. ;P
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #15 - Posted 2015-02-05 12:30:16 »

Different issue. "abc" is a single instance in the constant pool.  If another class also has "abc" in it they will (currently) be interned and have identical references.  The code above is explicitly making two duplicates via new.  So we now have (at least) three copies on heap.  The deduplication feature will (at some point) reduce the number.
This is exactly what I meant to... convey Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Roquen

JGO Kernel


Medals: 518



« Reply #16 - Posted 2015-02-05 13:40:09 »

Gotcha.
Offline KaiHH

JGO Kernel


Medals: 820



« Reply #17 - Posted 2015-02-06 18:48:23 »

Definitely go buy that book: http://www.javapuzzlers.com/
It is hilarious! The best Java book I read in, ...like..., all times.  Grin
It contains all those weird "corner-cases" of Java and makes you laugh out loud when reading the solution to some of those puzzles.
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (846 views)
2019-09-04 15:33:17

hadezbladez (5790 views)
2018-11-16 13:46:03

hadezbladez (2602 views)
2018-11-16 13:41:33

hadezbladez (6206 views)
2018-11-16 13:35:35

hadezbladez (1498 views)
2018-11-16 13:32:03

EgonOlsen (4733 views)
2018-06-10 19:43:48

EgonOlsen (5791 views)
2018-06-10 19:43:44

EgonOlsen (3275 views)
2018-06-10 19:43:20

DesertCoockie (4174 views)
2018-05-13 18:23:11

nelsongames (5500 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!