• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Searching/Removing arbitrary object in Generics

 
Ranch Hand
Posts: 361
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I came across the following statement in Java SCJP 6.0 Khalid Mughal.


Note that we can only add an object of a specific type (E). However, a collection
allows us to determine whether it has an element equal to any arbitrary object,
or remove an element that is equal to any arbitrary object.




I tried the following program.



I am not clear as to why the Generics allow Searching/Removing arbitrary object, when in the above case it can only store String.

Please advise.
 
Bartender
Posts: 11497
19
Android Google Web Toolkit Mac Eclipse IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Naresh Chaurasia wrote:
I am not clear as to why the Generics allow Searching/Removing arbitrary object, when in the above case it can only store String.


Why shouldn't it allow?
Consider a list of friends. Imagine they are stored as 'Friend' object.
Suppose you are no longer on talking terms with someone and you do not consider him as your 'friend' How would you remove him from the list if this search/remove ability did not exist?

Does this clear your doubt or did you mean something else?
 
Naresh Chaurasia
Ranch Hand
Posts: 361
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I mean in String array, I should be only allowed to search for String, and not integers
 
Marshal
Posts: 79179
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why? What is wrong with this sort of code?And what happens if you change the two occurrences of the word String to Object? Why should that not work?
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Campbell: What is wrong with that is that a List<String> never contains Integer objects. If it does, something is very wrong... it should not even be possible to add anything else than String objects to a List<String>. I know it's possible because of type erasure and when you do casts, but... And an array (instead of a List) of Strings can really never contain an Integer, because the JVM checks at runtime what you put into an array. If you try to put an Integer in a String[] you will get an ArrayStoreException.

Also, you should never create different classes which can be equal() to each other. It will cause you a lot of headaches...

Naresh: If you look at interface java.util.List<E> you'll see that it has a contains() method which takes an Object instead of an E.

This is because of backward compatibility. Generics have not been in the Java language since the start. They were added in Java 5. The collections interfaces and classes have been modified to support generics, but not all changes could be made without breaking backward compatibility. So, Oracle (or Sun at that time) decided to not change the method contains(Object obj) to contains(E obj), because it might have caused a compile error when compiling old code with the new Java version.

If they would redesign the API without regard for backward compatibility, there would probably have been a method contains(E obj) instead, but that's never going to happen - Oracle takes backward compatibility very seriously.
 
Campbell Ritchie
Marshal
Posts: 79179
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you.

Can you actually write a List#contains(E e) method? Would't it count as override‑equivalent with contains(Object)? In which case your String[] and your List<String> would be found not to contain that Integer.
 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oracle couldn't just add a contains(E) method:

Error:

C:\Temp>javac MyList.java
MyList.java:5: error: name clash: contains(E) and contains(Object) have the same erasure
boolean contains(E e);
^
where E is a type-variable:
E extends Object declared in interface MyList
1 error

 
Bartender
Posts: 2236
63
IntelliJ IDE Firefox Browser Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:Oracle couldn't just add a contains(E) method



They could have added a method that takes E with slightly different name and deprecate contains.

But why bother? Until today I was not aware that contains takes Object! And I've been using it a lot...
 
Campbell Ritchie
Marshal
Posts: 79179
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I still think contains(Object) is simpler. It might work better without erasure, then you could implement it like this:-
reply
    Bookmark Topic Watch Topic
  • New Topic