Newbie question: Can a parameterized container hold objects derivedfrom the parameter?

M

mrstephengross

I have two classes: Base and Derived (where Derived extends Base). I
also have a Set parameterized on Base (Set<Base>). Can I add a Derived
instance to my set?

The following code demonstrates this, and causes a ClassCastException:

class Base {};
clase Derived {};
Set<Base> set = new TreeSet<Base>();
set.add(new Derived()); // <-- Causes exception

Is there a way to make this work?

Thanks,
--Steve
 
L

Lars Enderin

mrstephengross skrev:
I have two classes: Base and Derived (where Derived extends Base). I
also have a Set parameterized on Base (Set<Base>). Can I add a Derived
instance to my set?

The following code demonstrates this, and causes a ClassCastException:

class Base {};
clase Derived {};
Set<Base> set = new TreeSet<Base>();
set.add(new Derived()); // <-- Causes exception

Is there a way to make this work?
Yes. Replace <Base> with <? extends Base>. See
http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html.
 
O

Owen Jacobson

I have two classes: Base and Derived (where Derived extends Base). I
also have a Set parameterized on Base (Set<Base>). Can I add a Derived
instance to my set?

The following code demonstrates this, and causes a ClassCastException:

  class Base {};
  clase Derived {};

I assume you mean class Derived extends Base {} here. Also, Java does
not require semicolons after class declarations.
  Set<Base> set = new TreeSet<Base>();
  set.add(new Derived()); // <-- Causes exception

The ClassCastException here has nothing to do with the relationship
between Base and Derived (and as written the error would be a compile-
time error about incorrect types; see previous remark about
'extends' :). TreeSet requires that either the elements themselves
implement Comparable or that you provide a Comparator at construction
time. If you don't provide a Comparator, it tries to cast elements to
Comparable when inserting them -- and since neither Base nor Derived
implements Comparable, this causes the CCE you're encountering.

Unless you need a set that's sorted, try another Set implementation
like HashSet that doesn't impose extra constraints on the contents.
If you do need a sorted set, make sure there's something to sort on!
Either make Base implement Comparable (correctly) or provide an
implementation of Comparator for Base when constructing the TreeSet.

-o
 
M

mrstephengross

The ClassCastException here has nothing to do with the relationship
between Base and Derived (and as written the error would be a compile-
time error about incorrect types; see previous remark about
'extends' :). TreeSet requires that either the elements themselves
implement Comparable or that you provide a Comparator at construction
time. If you don't provide a Comparator, it tries to cast elements to
Comparable when inserting them -- and since neither Base nor Derived
implements Comparable, this causes the CCE you're encountering.

Unless you need a set that's sorted, try another Set implementation
like HashSet that doesn't impose extra constraints on the contents.
If you do need a sorted set, make sure there's something to sort on!
Either make Base implement Comparable (correctly) or provide an
implementation of Comparator for Base when constructing the TreeSet.

Ok, I changed it around to implement Comparator. However, I'm still
getting a ClassCastException:

class Foo implements Comparator {
public int compare(Object o1, Object o2) { return 0; } }
class Bar extends Foo {}
SortedSet<Foo> set = new TreeSet<Foo> ();
set.add(new Bar()); // <-- Causes exception!

So Bar extends Foo, which implements Comparator. However, the
exception still occurs. Any ideas?

Thanks,
--Steve
 
O

Owen Jacobson

Ok, I changed it around to implement Comparator. However, I'm still
getting a ClassCastException:

  class Foo implements Comparator {
    public int compare(Object o1, Object o2) { return 0; } }
  class Bar extends Foo {}
  SortedSet<Foo> set = new TreeSet<Foo> ();
  set.add(new Bar()); // <-- Causes exception!

So Bar extends Foo, which implements Comparator. However, the
exception still occurs. Any ideas?

Yes: you've confused Comparator and Comparable.

Instances of Comparable classes can be compared to other instances of
the same Comparable class.

Instances of Comparator can be used to compare two instances of some
other class.

You probably want Foo to implement Comparable<Foo>.

-o
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top