编辑:删除了两组以前的解决方案。有关详细信息,请参阅编辑历史记录。
以下是对任意数量的集合递归执行此操作的方法:
public static Set<Set<Object>> cartesianProduct(Set<?>... sets) {
if (sets.length < 2)
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got " +
sets.length + ")");
return _cartesianProduct(0, sets);
}
private static Set<Set<Object>> _cartesianProduct(int index, Set<?>... sets) {
Set<Set<Object>> ret = new HashSet<Set<Object>>();
if (index == sets.length) {
ret.add(new HashSet<Object>());
} else {
for (Object obj : sets[index]) {
for (Set<Object> set : _cartesianProduct(index+1, sets)) {
set.add(obj);
ret.add(set);
}
}
}
return ret;
}
请注意,不可能将任何泛型类型信息与返回的集合一起保留。如果您事先知道要取多少个集合的乘积,则可以定义一个泛型元组来保存那么多元素(例如),但是在Java中没有办法拥有任意数量的泛型参数。Triple<A, B, C>