• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Casting in Generics, is it redundant?

 
S.R Paul
Ranch Hand
Posts: 30
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ranchers!
My question is about use casting in a TreeSet. Check the code below

It gives compiler warning about unchecked conversion.

warning: [unchecked] unchecked conversion
found : java.util.TreeSet
required: java.util.TreeSet<java.lang.Integer>
TreeSet<Integer> set = (TreeSet)times.headSet(100);


My questions are,
1. We declared both TreeSets as Integer type, then why do we need to cast again? (both are same in Collection and Type)
2. If so, then what is the specialty of using generics over non-generics here? (except the type safeness)
I feel redundancy over here, what do you think?
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the time.headSet() method returns a SortedSet<Integer>, not a TreeSet<Integer>. Since you can't assign directly from SortedSet<Integer> to TreeSet<Integer> (not all SortedSet<Integer>s are TreeSet<Integer>s) you have to explicitly cast the returned value from SortedSet<Integer> to TreeSet<Integer>. The problem in your code is that a TreeSet<Intgeger> is not the same as a TreeSet. A TreeSet allows any reference type into it, while a TreeSet<Integer> allows only Integers. So you get the unchecked conversion when assigning from TreeSet to the TreeSet<Integer>.

If I were doing this, I might not assume the value returned from the times.headSet() was a TreeSet (after all, does it matter what specific type it is?) and would do this:

No casting required and in doesn't make an assumption about the time that gets returned from headSet()
 
S.R Paul
Ranch Hand
Posts: 30
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks to Steve.

time.headSet() method returns a SortedSet<Integer>, not a TreeSet<Integer>

I should have check this before posting.

not all SortedSet<Integer>s are TreeSet<Integer>s

also helped to be clear

Thank you
 
Rob Spoor
Sheriff
Pie
Posts: 20659
64
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:If I were doing this, I might not assume the value returned from the times.headSet() was a TreeSet

I would actually assume it was not a TreeSet. The returned SortedSet NavigableSet is a view of the original TreeSet, and whenever you read "view" that usually means "instance of some unknown inner class".

In this case it would actually work, but that's because TreeSet is itself only a wrapper for a NavigableMap (by default a TreeMap), and headSet returns a new TreeSet wrapper around the original TreeMap's headMap.
 
Winston Gutkowski
Bartender
Pie
Posts: 10527
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:If I were doing this, I might not assume the value returned from the times.headSet() was a TreeSet (after all, does it matter what specific type it is?) and would do this:

No casting required and in doesn't make an assumption about the time that gets returned from headSet()

Totally agree, and I'd go further.

@S.R.Paul: If you're only worried about being able to use the headSet() method, then you don't really care what type 'times' is either, so:indeed, if you don't need to use it after that, you can simply make the last line:

Set<Integer> smallSet = times.headSet(100);

Winston
 
S.R Paul
Ranch Hand
Posts: 30
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Rob spoor and Winston

@Rob Spoor
In this case it would actually work, but that's because TreeSet is itself only a wrapper for a NavigableMap (by default a TreeMap)

Could you make it clear (or provide ref's)
How could a Set can be a Wrapper to a Map?
How could Map<K,V> can be converted into a Set<e>? (you know Key, Value and Element)

@Winston
indeed, if you don't need to use it after that, you can simply make the last line:

Set<Integer> smallSet = times.headSet(100);

Seems better, more broader type ref, less headache
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:... The returned SortedSet NavigableSet is a ...


Re: SortedSet/NavigableSet... Perhaps the strangest part of the TreeSet API: headSet(E element) returns a SortedSet, and headSet(E element, boolean inclusive) returns a NavigableSet. The difference is that the first is defined in the SortedSet interface and the second in the NavigableSet interface. But does the inclusive parameter add so much to the method signature as to require a type difference in the return? Why not just make the return type a SortedSet as well?
 
Winston Gutkowski
Bartender
Pie
Posts: 10527
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
S.R Paul wrote:How could a Set can be a Wrapper to a Map?
How could Map<K,V> can be converted into a Set<e>? (you know Key, Value and Element)

As I recall, most Sets are simply a container to a Map<K, Boolean>. There's almost no overhead in storing the Boolean (which I think is Boolean.TRUE in all cases); and pretty much all the constraints of a Set are the same as those of a key in a Map.

Winston
 
S.R Paul
Ranch Hand
Posts: 30
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Luke
But does the inclusive parameter add so much to the method signature as to require a type difference in the return? Why not just make the return type a SortedSet as well?

Ya, I thought so. Does inclusive of an element cause/need a return type change? Weird!!!

@Winston
As I recall, most Sets are simply a container to a Map<K, Boolean>

Getting interesting. Need more reading.

Anyway, thank you all for all the replies.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
S.R Paul wrote:How could a Set can be a Wrapper to a Map?
How could Map<K,V> can be converted into a Set<e>? (you know Key, Value and Element)

As I recall, most Sets are simply a container to a Map<K, Boolean>. There's almost no overhead in storing the Boolean (which I think is Boolean.TRUE in all cases); and pretty much all the constraints of a Set are the same as those of a key in a Map.

I think they've changed implementations of HashSet and TreeSet over time - they used to put the same reference in as both key and value. Now (JDK 7) they put in a reference to a privately-held Object instance, identified as PRESENT, for the value. However there's also Collections.newSetFromMap(Map<E,Boolean>), which works as Winston describes. Regardless, it doesn't matter much what the implementation puts into the value; it's the key that's important. Mostly.
 
Rob Spoor
Sheriff
Pie
Posts: 20659
64
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And that the value is not null, so some methods can be easily implemented. For example:
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, that's what I meant by "mostly".
 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:
Rob Spoor wrote:... The returned SortedSet NavigableSet is a ...


Re: SortedSet/NavigableSet... Perhaps the strangest part of the TreeSet API: headSet(E element) returns a SortedSet, and headSet(E element, boolean inclusive) returns a NavigableSet. The difference is that the first is defined in the SortedSet interface and the second in the NavigableSet interface. But does the inclusive parameter add so much to the method signature as to require a type difference in the return? Why not just make the return type a SortedSet as well?

If the second method returned SortedSet as well, you could not pass that to a method which would have a parameter declared as NavigableSet (or, generally, use methods specific to NavigableSet).

I believe this is so because NavigableMap/NavigableSet were added in Java 6, so as not to alter the old interfaces and to provide support for the new interfaces at the same time.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic