| Author |
Casting in Generics, is it redundant?
|
S.R Paul
Ranch Hand
Joined: Mar 22, 2012
Posts: 30
|
|
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?
|
=-- Anything less than immortality is a complete waste of time --=
|
 |
Steve Luke
Bartender
Joined: Jan 28, 2003
Posts: 3036
|
|
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()
|
Steve
|
 |
S.R Paul
Ranch Hand
Joined: Mar 22, 2012
Posts: 30
|
|
Thanks to Steve.
I should have check this before posting.
also helped to be clear
Thank you
|
 |
Rob Spoor
Sheriff
Joined: Oct 27, 2005
Posts: 19216
|
|
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.
|
SCJP 1.4 - SCJP 6 - SCWCD 5
How To Ask Questions How To Answer Questions
|
 |
Winston Gutkowski
Bartender
Joined: Mar 17, 2011
Posts: 4756
|
|
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
|
Isn't it funny how there's always time and money enough to do it WRONG?
|
 |
S.R Paul
Ranch Hand
Joined: Mar 22, 2012
Posts: 30
|
|
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
Joined: Jan 28, 2003
Posts: 3036
|
|
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
Joined: Mar 17, 2011
Posts: 4756
|
|
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
Joined: Mar 22, 2012
Posts: 30
|
|
@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
Joined: Mar 05, 2008
Posts: 2782
|
|
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
Joined: Oct 27, 2005
Posts: 19216
|
|
And that the value is not null, so some methods can be easily implemented. For example:
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2782
|
|
Yeah, that's what I meant by "mostly".
|
 |
Martin Vajsar
Bartender
Joined: Aug 22, 2010
Posts: 2331
|
|
Steve Luke wrote:
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.
|
 |
 |
|
|
subject: Casting in Generics, is it redundant?
|
|
|