my dog learned polymorphism*
The moose likes Java in General and the fly likes Casting in Generics, is it redundant? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Casting in Generics, is it redundant?" Watch "Casting in Generics, is it redundant?" New topic
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: 4167
    
  21

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.

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

Joined: Oct 27, 2005
Posts: 19654
    
  18

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 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7549
    
  18

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?
Articles by Winston can be found here
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: 4167
    
  21

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

Joined: Mar 17, 2011
Posts: 7549
    
  18

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: 2995
    
    9
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: 19654
    
  18

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: 2995
    
    9
Yeah, that's what I meant by "mostly".
Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3606
    
  60

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.
 
jQuery in Action, 2nd edition
 
subject: Casting in Generics, is it redundant?
 
Similar Threads
Generics
generics...
generics
Generics - Unchecked conversion warning
Generics