Problem using generics and Type Safety issues
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
publicabstractclass CompositeSortedSet<T>
implements SortedSet<T>{
//first and second sorted sets
protected SortedSet<T> setA;
protected SortedSet<T> setB;
// the composite "set"
protected List<T> values =new ArrayList<T>();
/** constractor using two sorted sets */
public CompositeSortedSet(SortedSet<T> setA, SortedSet<T> setB){
this.setA=setA;
this.setB=setB;
}
/**
* This method is responsible for the merging of values
* it must be implemented by an extender
*/
protectedabstractvoid mergeValues();
/**
* Returns an Iterator for the elements of this set.
*/
public SortedIterator<T> iterator(){
returnnew MergedSortedIterator
(this.values.iterator());
}
}
/** A nested class for SortedIterator implementation */
class MergedSortedIterator<T>implements SortedIterator<T>{
//the iterator
private Iterator<T> iter0;
/**
* constractor using a "sorted" iterator
* @param iter0 an iterator
* @pre iter0 is going from min to max
*/
public MergedSortedIterator(Iterator<T> iter0){
this.iter0 = iter0;
}
/** returns true iff there is another part to iterate */
publicboolean hasNext(){
return iter0.hasNext();
}
/** returns the next part */
public T next(){
return iter0.next();
}
/** removes the current part */
publicvoid remove(){
iter0.remove();
}
}
My problem, is that I get "Type Safety: The expression of type MergedSortedIterator needs unchecked conversion to conform SortedIterator<T>" marked on the method:
public SortedIterator<T> iterator().
How do I fix this problem?
Thanks in advance.
[3748 byte] By [
Widgeta] at [2007-11-27 4:55:41]

public SortedIterator<T> iterator() {
return new MergedSortedIterator<T>(this.values.iterator());
//^^^
}
Wow thanks a lot mate! I didn't see it, stupid me.I have another small question, I'll post it soon enough.
import java.util.*;
public class UnifiedSortedSet<T extends Comparable> extends CompositeSortedSet<T> {
/** a constractor using two SortedSets */
public UnifiedSortedSet(SortedSet<T> A, SortedSet<T> B){
super(A,B);
mergeValues();
}
/**
* Setting values to be the union of A and B
*/
protected void mergeValues(){
T temp; //a temp variable of T type
for (SortedIterator<T> iterA = this.setA.iterator();
iterA.hasNext();){
temp = iterA.next();
values.add(temp);
}
for (SortedIterator<T> iterB = this.setB.iterator();
iterB.hasNext();){
temp = iterB.next();
if (!values.contains(temp)){
values.add(temp);
}
}
Collections.sort(values);
}
}
Now I have the same "error" marked on the line :
Collections.sort(values);
However, changing it to this is not helping:
Collections.sort((List<T>)values);
How can I fix this?
Thanks in advance!
How are you compiling this code? I know you're only asking how to get rid of "unchecked" warnings, but it's difficult to address those issues without clearing up the compilation errors and design flaws. Before I could compile your original code I had to dummy up a SortedIterator interface, but then I couldn't help wondering why I was doing that. As written, both SortedIterator and MergedSortedIterator are completely pointless, since they just forward all method calls to the provided Iterator object. Since they also don't bring up any interesting generics-related issues, I think it's best to leave them out of the discussion for the moment.
Then, to get UnifiedSortedSet to compile, I had to declare it abstract, since it (like its parent class) doesn't provide implementations for any of the Set or SortedSet methods. That's okay for now, since we're only interested in the mergeValues() method, but that won't compile because you're calling iterator() on plain old SortedSets and expecting to get back SortedIterators. That's probably another design issue, so I changed it to use vanilla Iterators.
Finally, there's the "unchecked" warning when you call Collections.sort(values). If "values" had been declared as a List<T extends Comparable<T>>
there would be no warning, but that's not a viable solution. You would have to place the same restriction on CompositeSortedSet and its subclasses, and I don't think you want to do that. Mucking about with the type of UnifiedSortedSet, as you tried to do, might get rid of the warning, but that would be about as advisable as changing your brand in the middle of a cattle drive. Yippee-kai-yay, and all that.
I can see two ways to get rid the warning: declare "values" as a SortedSet<T> (or SortedSomething<T>, anyway) so you don't have to call sort() at all; or use the two-argument form of sort(): Collections.sort(values, comparator());
Of course, that leaves you with the problem of implementing comparator() appropriately, but that's a design issue (in other words, your problem ^_^). Here's some revised code that compiles without warnings and is otherwise as correct as I can make it without knowing exactly what you're trying to do: import java.util.*;
public abstract class CompositeSortedSet<T>
implements SortedSet<T> {
//first and second sorted sets
protected SortedSet<T> setA;
protected SortedSet<T> setB;
// the composite "set"
protected List<T> values = new ArrayList<T>();
/** constractor using two sorted sets */
public CompositeSortedSet(SortedSet<T> setA, SortedSet<T> setB){
this.setA = setA;
this.setB = setB;
mergeValues(); // do this here, NOT in subclasses
}
/**
* This method is responsible for the merging of values
* it must be implemented by an extender
*/
protected abstract void mergeValues();
/**
* Returns an Iterator for the elements of this set.
*/
public Iterator<T> iterator() {
return values.iterator();
}
}
import java.util.*;
public abstract class UnifiedSortedSet<T>
extends CompositeSortedSet<T> {
/** a constractor using two SortedSets */
public UnifiedSortedSet(SortedSet<T> A, SortedSet<T> B){
super(A, B);
}
/**
* Setting values to be the union of A and B
*/
protected void mergeValues() {
for (T temp : setA) {
values.add(temp);
}
for (T temp : setB) {
if (!values.contains(temp)){
values.add(temp);
}
}
Collections.sort(values, comparator());
}
}
First, thank you for the response.
What I did not mention, is that I am given an overriding class (interface) of SortedSet<T> which has no add() method, so I can't use your suggested code.
I cant declare List to be
List<T extends Comparable><T>>
it says
"Syntax error on token "extends", , expected".
More than that, I cant implement comparator() (I'm working too generically here).
So have you got other suggestion? Or an explanation how to define "values" as "extends Comparable" without this weird warning.
Just for a reminder, values is defined:
protected List<T> values = new ArrayList<T>();
Hope for an early response.
You may have run afoul of a long-running forum bug which causes it to mess up nested generics. My suggestion gets arround the bug (I put < in instead of <)When you put nested generic into a forum post the forum stupidly takes the nested component out of the intial <
Yeah I noticed this bug just now,well is it possible for someone to email me the exact definition of my "values" because I can't seem to manage defining it without getting errors (what could be wrong with T extends Comparable...).Thank you.
>
> definition of my "values" because I can't seem to
> manage defining it without getting errors (what could
> be wrong with T extends Comparable...).
>
What's wrong it that Comparable is, itself, a generic interface. Check the javadoc for Collections.sort for the correct parameterization.
I thought I'd entered this, actually it should be something like:
public class MyClass LESSTHAN T extends Comparable LESSTHAN ? super T>>
Thank you, but I told u to also email that definition because I really can't figure the exact form of this signature...(this forum bug makes it impossible to understand)
@malcolmmc, I don't think it's the forum software's fault this time (which makes for a refreshing change ^_^).
The problem is that the <T> in the declaration of "values" is a reference to the <T> in the class declaration, not a new type parameter; you can't change it. In order to use the one-argument sort() method, you would have to change the class declaration: public abstract class CompositeSortedSet<T extends Comparable<T>>
implements SortedSet<T> {
But then you have to do the same thing in the the subclass (unless somebody knows how to enforce such a restriction in descendant classes): public abstract class UnifiedSortedSet<T extends Comparable<T>>
extends CompositeSortedSet<T> {
Even if you do that, users are free to use a type that doesn't implement Comparable; all they'll get is a compiler warning, and they may not even see that. Besides, sorted collections are expected to support both sorting modes: natural order (when all elements implement Comparable) and explicit Comparators. These are the reasons why I recommended against this approach.
As for the problem with your custom SortedSet not having an add() method, I don't get it. You're using a List implementation from the standard library as the delegate now; why not use a TreeSet instead? Then you could use addAll() intead of add() and eliminate those loops. Anyway, I wasn't offering a solution for your overall problem; I don't have nearly information for that. I was just trying to answer your questions about generics and type safety.
As for the forum bug, you can either leave a space after the '<' (which looks like hell), or always use the < entity instead of '<'. But be aware that, if you go back to edit your post, all the entities will have been replaced, so you'll have to re-escape everything.
Help sometimes comes from an unexpected place,
Your suggested code did not do the trick,
however changing the signature to
public class UnifiedSortedSet<T extends Comparable><T>> extends CompositeSortedSet<T> {
did do the trick.
Thank you so much for your help,
I sure got wiser.