【问题标题】:Convert Stream<Stream<T>> to T[][] with Streams/Lambda's in Java使用 Java 中的 Streams/Lambda 将 Stream<Stream<T>> 转换为 T[][]
【发布时间】:2018-09-14 12:25:13
【问题描述】:

我正在寻找是否有更好的方法来解决我不得不使用这些签名的困境(注意:由于 Spock 测试,需要 T[][] 并且我提供 T[][] 作为数据提供者)

我的方法签名是:

public <T> T[][] createArrays(Class<T> clazz, T...items)

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

public static <T> Stream<Stream<T>> of(T...items)

并计算传入数组的所有排列。

我的解决方案是:手动重新输入,请原谅拼写错误:

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;
}

我尝试了 .map(s -> s.toArray(....)) 但无法使 T[] 强制转换工作,IntFunction 生成器工作,也无法使用 Array.newInstance 工作。我可能遗漏了一些东西,如果有任何建议,我将不胜感激。

保重并提前感谢您的宝贵时间!!

【问题讨论】:

  • 如果你对未经检查的演员没问题,试试T[][] lists = (T[][])streams.map(x -&gt; (T[])x.toArray()).toArray();
  • 感谢您的回复 Sweeper,我确实尝试过,但由于无法识别“T”的类型擦除,我遇到了问题。

标签: java arrays list java-8 java-stream


【解决方案1】:

你可以像这样使用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));
}

没有任何中间Lists。

有一种变体可以创建相同类型的数组而无需未经检查的强制转换,像这样

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));
}

但是由于没有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));
}

【讨论】:

  • 工作就像一个魅力 Holger,打字等等! @Shadov,接受这个答案,因为不会抛出异常。
  • 我从没想过要使用这样的模板,非常漂亮的技巧,我要保存起来以备将来使用!!!特维姆!!!
猜你喜欢
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 2020-03-15
  • 2017-10-08
  • 2018-08-18
  • 1970-01-01
相关资源
最近更新 更多