如何在不懒惰地从两个列表中重复的情况下获取每对无序元素?
How to get every unordered pair of elements, without repetition from two lists lazyly?
这与 发布的问题相同,但在 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<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;
}
我只是想让这个方法变得懒惰。有什么想法吗?
创建一个支持 add()
、remove()
等的惰性 Collection
非常复杂。但是您可以轻松地 return 和 Iterator
(这本质上是懒惰的)使用流:
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();
}
如果需要,上面的内容可以很容易地转换为 Iterable
:
Iterable<Entry<T, K>> iterable = () -> pairs(l1, l2);
@shmosel 提出的迭代器方法是个好主意,这是我的看法:
要使其适用于单个列表,传入列表必须相等。例如 1,2,3
和 1,2,3
将产生:
1=2 1=3 2=3
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();
}
这与
示例:如果有 [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<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;
}
我只是想让这个方法变得懒惰。有什么想法吗?
创建一个支持 add()
、remove()
等的惰性 Collection
非常复杂。但是您可以轻松地 return 和 Iterator
(这本质上是懒惰的)使用流:
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();
}
如果需要,上面的内容可以很容易地转换为 Iterable
:
Iterable<Entry<T, K>> iterable = () -> pairs(l1, l2);
@shmosel 提出的迭代器方法是个好主意,这是我的看法:
要使其适用于单个列表,传入列表必须相等。例如 1,2,3
和 1,2,3
将产生:
1=2 1=3 2=3
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();
}