当前位置: 首页 > 知识库问答 >
问题:

应用流的“collec()”进行计数。运动

闾丘冠玉
2023-03-14

我正在尝试创建一个自定义收集器,以便计算列表中的有效元素。我使用了一个已经提供的收集器:

arr.stream()
    .filter(e -> e.matches("[:;][~-]?[)D]"))
    .map(e -> 1)
    .reduce(0, Integer::sum);

但作为对自己的挑战,我想创建自己的定制收藏家,以便更好地理解它。这就是我被卡住的地方。

这可能是一些微不足道的事情,但我正在学习这一点,无法计算供应商、累加器和合路器。我想我还是不了解他们。例如,我有一个类似的流:

arr1.stream()
    .filter(e -> e.matches("[:;][~-]?[)D]"))
    .map(e -> 1)
    .collect(temporary array, adding to array, reduce);

AFAIK supplier是一个没有参数的函数,它返回一些东西。我研究了标准示例,它通常是新集合的方法参考,例如,ArrayList::new。我尝试使用常量-

我完全被难住了。

共有1个答案

朱锦
2023-03-14

您的部分问题可能是,显然无法为整数类型创建累加器,因为它是不可变的。

您可以从以下内容开始:

System.out.println(IntStream.of(1,2,3).reduce(0, Integer::sum));

您可以扩展到此:

System.out.println(IntStream.of(1,2,3).boxed()
    .collect(Collectors.reducing(0, (i1,i2)->i1+i2)));

甚至这个,它有一个中间映射函数

System.out.println(IntStream.of(1,2,3).boxed()
        .collect(Collectors.reducing(0, i->i*2, (i1,i2)->i1+i2)));

你可以用你自己的收藏家走这么远

Collector<Integer, Integer, Integer> myctry = Collector.of(
        ()->0, 
        (i1,i2)->{
            // what to do here?
        }, 
        (i1,i2)->{
            return i1+i2;
        }
    );  

累加器是将值折叠到可变结果容器中的函数,此处的关键字为可变。

那么,做一个可变整数

public class MutableInteger {
    private int value;
    public MutableInteger(int value) {
        this.value = value;
    }
    public void set(int value) {
        this.value = value;
    }
    public int intValue() {
        return value;
    }
}

现在:

Collector<MutableInteger, MutableInteger, MutableInteger> myc = Collector.of(
        ()->new MutableInteger(0), 
        (i1,i2)->{
            i1.set(i1.intValue()+i2.intValue());
        }, 
        (i1,i2)->{
            i1.set(i1.intValue()+i2.intValue());
            return i1;
        }
    );

然后:

System.out.println(IntStream.of(1,2,3)
        .mapToObj(MutableInteger::new)
        .collect(myc).intValue());

参考:使用不同组合器和累加器的流缩减示例

编辑:完成者只是对最终结果做任何事情。如果你不是故意设置的,那么它默认设置为IDENTITY_FINISH,即Function.identity(),表示只按原样返回最终结果。

编辑:如果你真的很绝望:

Collector<int[], int[], int[]> mycai = Collector.of(
        ()->new int[1], 
        (i1,i2)->i1[0] += i2[0], 
        (i1,i2)->{i1[0] += i2[0]; return i1;}
    );
System.out.println(IntStream.of(1,2,3)
        .mapToObj(v->{
            int[] i = new int[1];
            i[0] = v;
            return i;
        })
        .collect(mycai)[0]);
 类似资料:
  • 我需要基于另一个流过滤一个流,并获取所有匹配条目的计数。 我已经尝试了以下和各种其他组合,但它没有按预期工作。 这个想法是: < li >对于从0到256的每个数字(流1) < li >查看该号码是否出现在另一个列表中(流2 ),如果出现的话 < li >计算出现次数除以流2中的元素总数(18)。 < li >如果没有出现,请收集0。 这基本上是根据流 2 中的出现次数查找流 1 中数字的频率。

  • 我想知道这怎么会被COUNT然后ASC订购。 输出: 所需输出:

  • 编辑:从我的角度来看,这太含蓄了,但这个想法当然是一个可能的解决方案,它将是最快的(比调用两次流生成器更快,并且至少要分别执行两个操作): ...利用一次迭代,而不必在内存上加载整个集合。我在做答案并行化的测试

  • 本文向大家介绍使用Spark进行实时流计算的方法,包括了使用Spark进行实时流计算的方法的使用技巧和注意事项,需要的朋友参考一下 Spark Streaming VS Structured Streaming Spark Streaming是Spark最初的流处理框架,使用了微批的形式来进行流处理。 提供了基于RDDs的Dstream API,每个时间间隔内的数据为一个RDD,源源不断对RDD进

  • 给定一个数N,我需要找到从1到N至少有一个素数(2,3,5或7)的数的计数。 现在N可以高达10^18。解决这个问题的最佳方法是什么。 例句:设N=100,答案是64。 请帮助解决这个问题。 代码:这是主要功能,但显然不是好方法

  • 我正在构建一个有以下要求的应用程序,我刚刚开始使用Flink。 null null 谢谢并感激你的帮助。