如何使用Java8流以特定的方式实现zip?

如何使用Java8流以特定的方式实现zip?,java,java-8,java-stream,Java,Java 8,Java Stream,我试图弄清楚如何使用Streams API实现一个zip函数,该函数以无限多的int[]作为参数;从每个元素中获取第i个元素;将它们放在一个元组中(显然需要一个自定义的元组对象,我有),并返回一个元组列表(即list) 基本上是为了: { 1, 2, 3 } { 4, 5, 6 } 建议的方法应返回: [元组(1,4),元组(2,5),元组(3,6)]作为java.util.List 下面是一个函数,它以“正常”的方式执行我尝试执行的操作: /** *返回元组列表,其中每个元组包含第i个元素

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

基本上是为了:

{ 1, 2, 3 }
{ 4, 5, 6 }
建议的方法应返回:
[元组(1,4),元组(2,5),元组(3,6)]
作为
java.util.List

下面是一个函数,它以“正常”的方式执行我尝试执行的操作:

/**
*返回元组列表,其中每个元组包含第i个元素
*从每个参数序列。返回的列表是
*长度被截断为最短参数序列的长度。
*
*@param args要包装在{@link Tuple}中的整数数组
*@返回元组列表
*/
公共静态列表zip(int[]…args){
List retVal=new ArrayList();
//查找具有最小大小的数组
int minLength=Arrays.stream(args).map(i->newinteger(i.length)).min((a,b)->a.compareTo(b)).get();
对于(int i=0;i
解决方案是在索引上创建一个流,并使用
mapToObj
将每个
int
映射到
元组中。另外,由于您已经有了一个
Builder
对象,我们可以利用它将元素收集到其中

假设我们添加一个方法
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());
}
公共静态列表zip(int[]…args){
//查找具有最小大小的数组
int minLength=Arrays.stream(args).mapToInt(i->i.length).min().orElse(0);
返回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)->{throw new IllegalStateException();}
抛出异常,而不添加
addAll
方法。)



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

如果您的
Tuple
类型支持从int数组创建一个Tuple,则替换
collect(…).build()可能更简单
通过简单的
toArray()
调用内部流的一部分,并根据结果创建元组。
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());
}