Here's my code:
public class Sequence<T> {
protected List<T> sequence = new ArrayList<T>();
public Matrix<OrderedPair<T, ?>> createCartesianProduct(Sequence<?> secondSequence) {
Matrix<OrderedPair<T, ?>> result = new Matrix<OrderedPair<T, ?>>();
for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) {
Sequence<OrderedPair<T, ?>> row = new Sequence<OrderedPair<T, ?>>();
for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) {
row.add(new OrderedPair(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));
}
}
return result;
}
}
This compiles in Eclipse, but on the line within the inner for loop ( row.add(...) ) I get the following three warnings:
OrderedPairis a raw type. References to generic typeOrderedPair()<T1, T2>should be parameterized.- Type Safety: The expression of type OrderedPair needs unchecked conversion to conform to
OrderedPair<T, ?> - Type safety: The Constructor OrderedPair(Object, Object) belongs to the raw type OrderedPair. References to generic type OrderedPair
<T1, T2>should be parameterized
I would like to use generics to enforce strong type-checking here, but I guess my understanding of generics is not sufficient to allow me to see how. Could someone educate me?
Thanks,
-- Ken
-
Trust compiler and try to use generic parameters always when calling for OrderedPair :) It's not required but I think it's a good practice.
Strict generic applying in Java is not possible because of this:
-
All you need to do is add a generic type to your constructor, like so:
row.add(new OrderedPair<T, ?>(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));The compiler is throwing errors since
OrderedPairexpects to receive types<T, ?>while you are passing them without any explicit type. Theunchecked conversionthe compiler is talking about is since basically you are giving the constructor<?, ?>while it wants<T, ?>hence the unchecked conversion that is going on, and which might throw an exception if the wrong type accidentally gets passed. -
The constructor in the inner for loop should have generics:
row.add(new OrderedPair<T, ?>(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)));If the compiler complains about the "
?" (I think it will, but it's not easy for me to test), then replace all the?'s with a letter, sayE. Then add an<E>into the signature, like this:public<E>Matrix<OrderedPair<T, E>> createCartesianProduct(Sequence<E> secondSequence) {(otherwise, the compiler won't know where the
Ecame from).newacct : You definitely need to add the E there because you definitely need to enforce that the E in secondSequence and the E in the return are the same type. ? won't work because (1) you cannot instantiate an object with a ? type parameter, and (2) you cannot add any elements to an object with a ? type parameter (so the .add() would fail) because you cannot guarantee that the element is a subtype of "?" (some unknown type). So the E is definitely needed. -
The OrderedPair is not generified but it's added to a list (Sequence) which is generified. You have to construct the OrderedPair with generics, e.g. do "new OrderedPair<...>(...)", to get rid of this warning.
Here I have added generics to the whole method, so the return type matches the secondSequence's type:
public <Z> Matrix<OrderedPair<T, Z>> createCartesianProduct(Sequence<Z> secondSequence) { Matrix<OrderedPair<T, Z>> result = new Matrix<OrderedPair<T, Z>>(); for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) { Sequence<OrderedPair<T, Z>> row = new Sequence<OrderedPair<T, Z>>(); for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) { addToRow(row, sequence.get(rowIndex), secondSequence.sequence.get(columnIndex)); } } return result; } static <T, Z> void addToRow(Sequence<OrderedPair<T, Z>> seq, T t, Z z) { seq.add(new OrderedPair<T, Z>(t, z)); } -
Hi Ken.
I think that you are a bit confused here. In the type
Sequence<T>what will be theT?If you define a
Sequence<OrderedPair<T, ?>>then you end up with recursion on T.Please see if what you really need is something like this:
public class Sequence<T> { protected List<T> sequence = new ArrayList<T>(); public <T2> Matrix<OrderedPair<T, T2>> createCartesianProduct(Sequence<T2> secondSequence) { Matrix<OrderedPair<T, T2>> result = new Matrix<OrderedPair<T, T2>>(); for (int rowIndex = 0; rowIndex < sequence.size(); rowIndex++) { Sequence<T> row = new Sequence<T>(); for (int columnIndex = 0; columnIndex < secondSequence.length(); columnIndex++) { row.add(new OrderedPair<T, T2>(sequence.get(rowIndex), secondSequence.sequence.get(columnIndex))); } } return result; } }
0 comments:
Post a Comment