填充数组的内联函数

Inline function filling an array

是否有任何方法可以使用内联 function/lambda 在 Java 中声明和填充数组,如下所示?

final int NUM_NAMES = 10;
String names = () -> {
    ArrayList<String> names = new ArrayList();
    for (int i = 0; i < NUM_NAMES; i++) {
        names.add("Name " + i);
    }
    return names.toArray();
};

您可以使用以下内容:

List<String> names = IntStream.range(0, 10)
    .boxed()
    .map(i -> String.format("Name %d", i))
    .collect(Collectors.toList())

希望那里的语法没问题,但你明白了。

技术上可以内联执行此操作,但语法非常冗长:

String[] names = ((Supplier<String[]>)() -> {
  ArrayList<String> namesList = new ArrayList<>();
  for (int i = 0; i < NUM_NAMES; i++) {
    namesList.add("Name " + i);
  }
  return namesList.toArray(new String[0]);
}).get();

所以我不推荐它。您必须指定 lambda 表达式的类型,转换为该类型,然后将整个转换表达式放在括号中,以便您可以调用 get 来获取生成的数组。

一种更简洁的内联初始化数组的方法是像这样的辅助方法(这是受 Kotlin 数组构造函数的启发):

public static <T> T[] buildArray(T[] arr, IntFunction<T> elementFunction) {
    for (int i = 0 ; i < arr.length ; i++) {
      arr[i] = elementFunction.apply(i);
    }
    return arr;
}

在第二个参数中,指定每个索引需要的元素:

String[] names = buildArray(new String[NUM_NAMES], i -> "Name " + i);

可能最短的方法是使用 Arrays.setAll,它可用于在任何类型的数组中设置值,以及用于确定每个索引值的索引值生成器:

String[] names = new String[NUM_NAMES];
Arrays.setAll(names, i -> "Name " + i);

不幸的是,Arrays.setAll 没有 return 数组,因此您不能将 names 的整个声明放在一行中。