Linq C#中Java的Stream#Peek方法的等价物是什么?

时间:2017-07-07 21:33:00

标签: java c# linq java-8 java-stream

我已经习惯使用Java的 Stream#Peek 方法,因为它是调试中间流操作的有用方法。对于那些不熟悉 Stream#Peek 方法的人,下面显示了它的定义:

  

Stream<T> peek(Consumer<? super T> action)

     

返回由此流的元素组成的流,   另外对每个元素执行提供的操作   从结果流中消耗元素。这是个   中间操作。

请考虑以下简单示例:

List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<Integer> result = integerList.stream()
                                  .filter(i -> i % 2 == 0)
                                  .peek(System.out::println)
                                  .collect(Collectors.toList());

使用 Stream#Peek 方法,这应该基本上允许我将所有偶数打印到控制台,以便我可以测试以查看这是否是我所期望的

我试图找到问题的答案,但似乎无法在C#中找到类似的方法,是否有人知道Java的强大等同于 {{ 3}} 或其他一些行为相似的方法?

3 个答案:

答案 0 :(得分:6)

LINQ中没有等效的Peek - 即没有执行某些操作的方法返回源元素。 ForEach类中有一个List方法对每个元素执行操作,但它不返回源元素,如前所述,它不是IEnumerable扩展名

但是你可以轻松编写自己的扩展名

public static IEnumerable<T> Peek<T>(this IEnumerable<T> source, Action<T> action)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (action == null) throw new ArgumentNullException(nameof(action));

    return Iterator();

    IEnumerable<T> Iterator() // C# 7 Local Function
    {
       foreach(var item in source)
       {
           action(item);
           yield return item;
       }
    }
}

答案 1 :(得分:4)

您可以使用Select Statement Lambda来实现此目的。考虑:

var integerList = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var result = integerList
    .Where(i => i % 2 == 0)

    // this select uses a statement lambda
    .Select(i =>
    {
        Console.WriteLine(i);
        return i;
    })

    .Whatever(...);

答案 2 :(得分:1)

编辑:在对原始问题进行编辑后,此答案已过时。最初的问题的目的是peek - 所有filter - ed值,然后执行findFirst

List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> result = integerList.stream()
                                      .filter(i -> i % 2 ==0== 0)
                                      .peek(System.out::println)
                                      .findFirst();

据我所知,没有内置的LINQ解决方案,所以这是一个扩展方法:

public static IEnumerable<T> Peek<T>(this IEnumerable<T> source, Action<T> action)
{
    using (var iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            action(iterator.Current);
        }
    }

    using (var iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            yield return iterator.Current;
        }
    }
}

用法:

var integerList = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int? result = integerList.Where(i => i % 2 == 0)
                         .Peek(i => Console.WriteLine(i))
                         .FirstOrDefault();

Console.WriteLine(result);

输出:

2
4
6
8
10
2