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

如何使用Java 8 Streams以特定的方式实现zip?

宋臻
2023-03-14

我试图弄清楚如何使用Streams API实现一个zip函数,该函数以无限多的int[]作为参数;从每个元素中获取i'th元素;将它们放在一个元组中(显然需要一个自定义的元组对象-我有),并返回一个元组列表(即list)。

本质上,为:

{ 1, 2, 3 }
{ 4, 5, 6 }

建议的方法应该以java的形式返回:[元组(1,4),元组(2,5),元组(3,6)]。util。列表

这是一个函数,它以“正常”的方式完成了我试图做的事情:

/**
 * Return a list of tuples, where each tuple contains the i-th element
 * from each of the argument sequences.  The returned list is
 * truncated in length to the length of the shortest argument sequence.
 *
 * @param args  the array of ints to be wrapped in {@link Tuple}s
 * @return a list of tuples
 */
public static List<Tuple> zip(int[]... args) {
    List<Tuple> retVal = new ArrayList<>();
    // Find the array with the minimum size
    int minLength = Arrays.stream(args).map(i -> new Integer(i.length)).min((a, b) -> a.compareTo(b)).get();

    for(int i = 0;i < minLength;i++) {
        Tuple.Builder builder = Tuple.builder();
        for(int[] ia : args) {
            builder.add(ia[i]);
        }
        retVal.add(builder.build());
    }

    return retVal;
}

共有1个答案

严狐若
2023-03-14

一种解决方案是在索引上创建一个Stream,并使用mapToObj将每个int映射到Tuple中。此外,由于您已经有了Builder对象,我们可以利用它将元素收集到其中。

假设我们添加一个方法<代码>元组。建设者addAll(Tuple.Builder other)其目的是将一个生成器添加到另一个生成器,我们可以有以下代码:

public static List<Tuple> zip(int[]... args) {
    // Find the array with the minimum size
    int minLength = Arrays.stream(args).mapToInt(i -> i.length).min().orElse(0);

    return IntStream.range(0, minLength)
                    .mapToObj(i -> 
                       Arrays.stream(args)
                             .mapToInt(ia -> ia[i])
                             .collect(Tuple::builder, Tuple.Builder::add, Tuple.Builder::addAll)
                             .build()
                    ).collect(Collectors.toList());
}

(如果您不想支持并行执行,您可以使用(b1, b2)-

作为补充说明,查找最小数组大小的代码可以简化:您不需要将其装箱为整数,只需将每个数组映射到其长度,并使用最小值()。这将返回一个可选值;我没有获取它的值(如果流为空,则可能引发异常),而是使用了orElse(0),以便在流为空的情况下,返回一个空列表。

 类似资料:
  • 问题内容: ls命令以以下格式打印时间: 我如何转换,从接收到的时间的这个格式的本地时间? 问题答案: 使用strftime(您需要先转换为): 格式: 这是完整的代码:

  • 问题内容: 在游戏中,输出一个随机数(loadG1)并显示4秒钟。一旦四秒钟结束,它就会消失,用户必须输入其值才能获得分数。一旦用户按下Enter键,他们的输入框就会消失,程序必须等待直到更长的CountDownTimer(当前为18秒)结束才可以看到他们的分数。到目前为止,他们只能得分1分。我想发生的是,一旦输入答案(无论是否正确),就重复4秒倒数计时器的内容。虽然,我希望在再次启动倒数计时器时

  • 我有一个源类,它将字符串属性定义为CharSequence(不幸的是)。 所以如下: 给我: 无法将属性“java.lang.CharSequence charSeq”映射到“java.lang.String str”。考虑声明/实现一个映射方法:“java.lang.String map(java.lang.CharSequence value)” 我如何实现这个映射器方法,并使它对我的所有映射

  • 问题内容: 我有一个在Hudson奴隶上运行的项目。我希望其中之一在Java6而不是默认值(我的环境中为Java5)下运行Ant。 在项目配置视图中,我希望找到以下两者之一: 一个显式选项,允许我设置一个自定义JDK位置以用于该项目。 一种为该项目设置自定义环境变量的方法,这将允许我将JAVA_HOME设置为JDK6位置。这将使Ant能够根据需要在Java6上运行。 有什么办法可以做到以上任一?如