I'm a Java noob with a bit of C++ experience and I'm trying to create a Set of Sets in Java along the following lines (similar to what one would do in C++):
Set< Set< String > > collection = new TreeSet< Set< String > >();
Set< String > entry = new TreeSet< String >();
collection.add( entry );
This builds fine, but then when the program is executed, a java.util.TreeSet cannot be cast to java.lang.Comparable
exception is thrown.
Without reimplementing the wheel, how can one have a Set of Sets in Java?
Also, what is the deal with Java allowing broken code (e.g., the type mismatch) to compile?
Thanks in advance for any feedback.
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.
A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.
Generics should be used instead of raw types ( Collection< T > instead of Collection , Callable< T > instead of Callable , …) or Object to guarantee type safety, define clear type constraints on the contracts and algorithms, and significantly ease the code maintenance and refactoring.
In the contract of TreeSet
, the requirement is laid out that all entries have to be Comparable
or you have to provide a Comparator
. (This is also why you didn't see a compile-time error: entries are only cast to Comparable
in the absence of an explicit Comparator
.)
It's got nothing to do with generics, it comes from the implementation of TreeSet
itself: as it's a binary tree, it only makes sense if the entries can be ordered somehow.
If you tell a bit more about your specific problem, we can probably help you find the exact data structure you need but in general, if you don't care about the order of elements in a set, a HashSet
is used. And again, in general, a Set
of Set
s is often a sign of sloppy design.
If you want to add an object to a TreeSet
collection, that object's type must implement the Comparable
interface, which TreeSet
itself does not. Alternatively, you can provide a Comparator
by creating the TreeSet with a different constructor.
It doesn't really make sense to use a TreeSet
for this particular scenario because this is by definition an ordered collection and you don't seem to need an ordering of elements. You could try a HashSet
instead.
Furthermore, to answer your second question, this error only appears at runtime because you are exploiting polymorphic behavior i.e. you are adding to a Set
, which actually at runtime is bound to a TreeSet
. This information is not known at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With