Кажется немного произвольным определить ваш класс CrossProduct
таким образом: почему переменные-члены списка аргументов, тогда как fn
является параметром метода? На самом деле, почему CrossProduct
вообще класс? Список перекрестных произведений is a
, но это не подтип списка, поскольку данный список может одновременно
- можно выразить как перекрестное произведение многими различными способами, а
- не были созданы с использованием функции
crossproduct
.
Не вполне естественно думать о «перекрестном произведении» как о типе, ИМО.
Я бы, наверное, сделал что-то вроде
public class ListFunctions {
public static <T1, T2, T3> List<T3> crossProduct(List<T1> list1, List<T2> list2, Function<T1, T2, T3> fn) {
List<T3> product = new ArrayList<T3>();
for (int i = 0; i < list1.size(); i++)
for (int j = 0; j < list2.size(); j++)
product.add(fn.function(list1.get(i), list2.get(j)));
return product;
}
}
Если бы вы по какой-то причине захотели определить класс CrossProduct
(например, реализовать ленивую оценку, как предложил Салман), я бы сказал, что лучше использовать все три аргумента в качестве переменных-членов и реализовать класс List
, например
public class CrossProduct<T1, T2, T3> implements List<T3> {
public CrossProduct(T1 list1, T2 list2, Function<T1, T2, T3> fn) {
// remember args...
}
// etc...
}