使用Java中的Streams/Lambda将Stream <Stream <T >>转换为T [] []

Jav*_*aJd 4 java arrays list java-8 java-stream

我希望看看有没有更好的方法来解决我必须使用这些签名的困境(注意:由于Spock测试需要T [] []并且我提供T [] []作为数据提供者)

我的方法签名是:

public <T> T[][] createArrays(Class<T> clazz, T...items)
Run Code Online (Sandbox Code Playgroud)

我正在使用具有签名的静态方法:

public static <T> Stream<Stream<T>> of(T...items)
Run Code Online (Sandbox Code Playgroud)

并计算传递数组的所有排列.

我的解决方案,手动重写,原谅错别字,是:

public static <T> T[][] createArrays(Class<T> clazz, T...items){
  Stream<Stream<T>> streams = EnumPerm.of(items);
  List<List<T>> lists = streams.map(s -> ).collect(toList()).collect(toList());
  T[][] outer = (T[][])(Array.newInstance(clazz,lists.size(),items.length);
  for(int x=0;x<lists.size();x++){
    List<T> innerList = lists.get(x);
    for(int y=0;y<items.length;y++){
      outer[x][y] = innerList.get(x);
    }      
  }

  return outer;
}
Run Code Online (Sandbox Code Playgroud)

我尝试了.map(s - > s.toArray(....))但是无法使T []转换为工作,IntFunction生成器工作,也没有使用Array.newInstance工作.我可能错过了一些东西,非常感谢任何建议.

请小心并提前感谢您的时间!

Hol*_*ger 5

你可以Array.newInstance像这样使用:

public static <T> T[][] createArrays(Class<T> clazz, T... items) {
    Stream<Stream<T>> streams = EnumPerm.of(items);
    return streams
        .map(s -> s.toArray(len -> (T[])Array.newInstance(clazz, len)))
        .toArray(len -> (T[][])Array.newInstance(items.getClass(), len));
}
Run Code Online (Sandbox Code Playgroud)

没有任何中间人List.

有一种变体可用于创建相同类型的数组而不使用未经检查的强制转换,如下所示

public static <T> T[][] createArrays(Class<T> clazz, T... items) {
    Stream<Stream<T>> streams = EnumPerm.of(items);
    T[] template = Arrays.copyOf(items, 0);
    return streams
        .map(s -> s.toArray(len -> Arrays.copyOf(template, len)))
        .toArray(len -> (T[][])Array.newInstance(template.getClass(), len));
}
Run Code Online (Sandbox Code Playgroud)

但由于没有现有的类型数组T[][],我们无法避免Array.newInstance创建外部数组.但请注意,不需要clazz参数.

如果要强制使用clazz所有数组的指定参数,可以使用

public static <T> T[][] createArrays(Class<T> clazz, T... items) {
    Stream<Stream<T>> streams = EnumPerm.of(items);
    return streams
        .map(s -> s.toArray(len -> (T[])Array.newInstance(clazz, len)))
        .toArray(len -> (T[][])Array.newInstance(clazz, len, 0));
}
Run Code Online (Sandbox Code Playgroud)