如何获取每一个无序的元素,而不是懒惰地从两个列表中重复?

时间:2017-02-27 22:28:54

标签: java iterator java-stream lazy-evaluation iterable

这是here发布的问题,但在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;
}

我只想让方法变得懒惰。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

创建一个支持Collectionadd()等的惰性remove()非常复杂。但是您可以使用流轻松返回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);

答案 1 :(得分:0)

@shmosel提出的迭代器方法是一个好主意,这是我的看法:

要使其适用于单个列表,传入列表必须相同。例如,1,2,31,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();
}