Java 如何获得每一个无序的元素对,而不必懒懒地重复两个列表?
这是同样的问题,但在Java中,因为在C中,yield可以解决我的问题 示例:如果有[1,2][5,6]。我想得到[1,5][1,6][2,5][2,6] 但如果我只有一个列表[1,2,3],结果将是[1,2][1,3][2,3] 这就是我所拥有的:Java 如何获得每一个无序的元素对,而不必懒懒地重复两个列表?,java,iterator,java-stream,lazy-evaluation,iterable,Java,Iterator,Java Stream,Lazy Evaluation,Iterable,这是同样的问题,但在Java中,因为在C中,yield可以解决我的问题 示例:如果有[1,2][5,6]。我想得到[1,5][1,6][2,5][2,6] 但如果我只有一个列表[1,2,3],结果将是[1,2][1,3][2,3] 这就是我所拥有的: public static <T,K> Collection<Entry<T,K>> Pairs (List<T> l1, List<K> l2) { Collection<
public static <T,K> Collection<Entry<T,K>> Pairs (List<T> l1, List<K> l2)
{
Collection<Entry<T,K>> result = new LinkedList<>();
for(int i =0;i<l1.size();i++)
{
for(int j=(l1==l2?i+1:0);j<l2.size();j++)
{
result.add(new Entry<>(l1.get(i),l2.get(j)));
}
}
return result;
}
公共静态集合对(列表l1、列表l2)
{
收集结果=新建LinkedList();
对于(int i=0;i来说,创建一个支持add()
、remove()
等的惰性集合是非常复杂的。但是,您可以使用流轻松返回一个迭代器(它本质上是惰性的):
public static <T, K> Iterator<Entry<T, K>> pairs(List<T> l1, List<K> l2) {
return IntStream.range(0, l1.size())
.mapToObj(i -> IntStream.range(l1 == l2 ? i + 1 : 0, l2.size())
.mapToObj(j -> new Entry<>(l1.get(i), l2.get(j))))
.flatMap(Function.identity())
.iterator();
}
@shmosel提出的迭代器方法是个好主意,以下是我的观点:
为使其适用于单个列表,传入列表必须相等。例如1,2,3
和1,2,3
将产生:
1=2 1=3 2=3
公共静态迭代器测试(左列表、右列表){
返回IntStream.range(0,left.size()).boxed().flatMap(i->left.equals(right)
?left.stream().skip(i+1.map)(j->newAbstractMap.SimpleEntry(left.get(i),j))
:right.stream().map(j->newAbstractMap.SimpleEntry(left.get(i),j)))
.iterator();
}
创建一个懒惰的集合并不容易。Iterable
或Iterator
足够吗?@shmosel这正是我想要的。非常好的答案,+1用于使用flatMap(Function.identity())
。导致Eclipse编译器出现类型不匹配问题,但通过在内部mapToObj
之前和点之后添加
很容易解决。@MarkusBenko在Eclipse中使用AbstractMap.SimpleEntry
为我工作。奇怪。复制并粘贴了代码,添加了一个带有两个参数的简单条目实现nd Eclipse 4.4.2并在此处抛出以下错误:类型不匹配:无法从迭代器转换为迭代器
@MarkusBenko我使用的是4.6.2。这可能是一个旧错误。
Iterable<Entry<T, K>> iterable = () -> pairs(l1, l2);
public static Iterator<AbstractMap.SimpleEntry<Integer, Integer>> test(List<Integer> left, List<Integer> right) {
return IntStream.range(0, left.size()).boxed().flatMap(i -> left.equals(right)
? left.stream().skip(i + 1).map(j -> new AbstractMap.SimpleEntry<>(left.get(i), j))
: right.stream().map(j -> new AbstractMap.SimpleEntry<>(left.get(i), j)))
.iterator();
}