Преобразовать потокT [] [] с потоками / лямбдами в Java - PullRequest
0 голосов
/ 14 сентября 2018

Я смотрю, есть ли лучший способ решить мою дилемму, заключающуюся в использовании этих подписей (примечание: 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 для работы.Я, вероятно, что-то упускаю и буду очень признателен за любые предложения.

Берегите себя и поблагодарите вас за заранее подготовленное время !!

1 Ответ

0 голосов
/ 14 сентября 2018

Вы можете использовать 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));
}

без каких-либо промежуточных 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));
}

но поскольку не существует существующего массива типа 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));
}
...