这样做的一个简单方法是遍历数组 T[] 并分配其类型 V 的字段并填充新数组。 但是,是否有更高效/优雅的方式(可能是 Java 中的内置功能)?
编辑: 我试过的代码:
Locale[] locs = Locale.getAvailableLocales();
String[] coutries = new String[locs.length] ;
for (int i = 0; i < locs.length; i++) {
coutries[i] = locs[i].getDisplayCountry();
}
编辑2: 对于大约 200 个元素的小数组,似乎在流上使用 map 操作更快,这是第二种方法:
coutries = Arrays.stream(locs).map(Locale -> Locale.getDisplayCountry()).toArray(String[]::new);
最佳答案
如果你正在使用 java-8 ,你可以在 map
上使用 Stream
操作:
V[] arr = Arrays.stream(arrayOfTypeT).map(t -> t.v).toArray(V[]::new);
甚至更好(如果封装良好)
V[] arr = Arrays.stream(arrayOfTypeT).map(T::getV).toArray(V[]::new);
所以这是基准(请注意,我不是 JMH 专家):
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class Benchmark {
static Integer[] ints = IntStream.range(0, 1_000_000).boxed().toArray(Integer[]::new);
public static void main(String... args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + Benchmark.class.getSimpleName() + ".*")
.forks(1)
.warmupIterations(20)
.build();
new Runner(opt).run();
}
@GenerateMicroBenchmark
public void standardForLoop() {
final String[] arr = new String[ints.length];
for (int i = 0; i < ints.length; i++) {
arr[i] = String.valueOf(ints[i]);
}
}
@GenerateMicroBenchmark
public void forEachLoop() {
final String[] arr = new String[ints.length];
for (int i : ints) {
arr[i] = String.valueOf(i);
}
}
@GenerateMicroBenchmark
public void streamMapOperation() {
@SuppressWarnings("unused")
String[] arr = Arrays.stream(ints).map(String::valueOf).toArray(String[]::new);
}
@GenerateMicroBenchmark
public void streamParallelMapOperation() {
@SuppressWarnings("unused")
String[] arr = Arrays.stream(ints).parallel().map(String::valueOf).toArray(String[]::new);
}
}
结果:
Benchmark Mode Samples Mean Mean error Units
b.Benchmark.forEachLoop avgt 20 58,455 2,359 ms/op
b.Benchmark.standardForLoop avgt 20 59,214 2,415 ms/op
b.Benchmark.streamMapOperation avgt 20 62,877 2,887 ms/op
b.Benchmark.streamParallelMapOperation avgt 20 40,171 6,456 ms/op
如您所见,对于庞大的数据集,标准循环和流方法之间没有太大区别。但是使用流方法,您可以轻松调用 parallel()
,这使计算效率稍微高一些(当然您可以编写自己的多线程实用程序来执行此操作,但这需要一些工作在你身边)。
请注意,由于线程设置、同步等因素,parallel()
对于小数据集的效率可能较低。因此不要过早进行优化。首先衡量您的代码,如果确实存在性能问题,请尝试调查问题所在和原因。
关于java - 当 V 是 T 中的属性对象时,如何将数组 T[] 转换为 V[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27588663/