java - 用于转换不可变列表的 Guava 单线

标签 java guava

我认为必须有一个单行 Guava 解决方案来将一个不可变列表转换为另一个不可变列表,但我找不到它。假设我们有以下对象:

ImmutableList<String> input = ImmutableList.of("a", "b", "c");
Function<String, String> function = new Function<String, String>() {
    @Override
    public String apply(String input) {
        return input + input;
    }
};

转换可以这样实现:

Iterable<String> transformedIt = Iterables.transform(input, function);
ImmutableList<String> output = ImmutableList.<String>builder().addAll(transformedIt).build();

或者像这样:

List<String> transformedList = Lists.transform(input, function);
ImmutableList<String> output2 = ImmutableList.copyOf(transformedList);

但我认为对于这种转换必须有一个性能优化的单线,没有中间对象,我就是找不到它。它在哪里?

最佳答案

您可以简单地删除您的构建器并内联它以获得(更长的)单行

ImmutableList<String> output =
    ImmutableList.copyOf(Iterables.transform(input, function));

这是一种优化,因为 Iterables.transform 的结果是惰性的,因此不会分配临时列表。 AFAIK 有一些小的低效率:

  • 分配一个FluentIterable
  • 调整用于结果的数组的大小

如果您真的很在意速度,可以对其进行基准测试并与类似的东西进行比较

ArrayList<String> tmp = Lists.newArrayListWithCapacity(input.size());
Iterables.addAll(tmp, Iterables.transform(input, function));
ImmutableList<String> output = ImmutableList.copyOf(tmp);

到一个手动循环。

更新

虽然第一种方法肯定是最易读的方法,但它会导致数组调整大小以及最终缩小到所需大小的一些分配。对于长度为 1234567 的列表,有以下调整大小的步骤:

4 -> 7 -> 11 -> 17 -> 26 -> 40 -> 61 -> 92 -> 139 -> 209 -> 314 -> 472 -> 709 -> 1064 -> 1597 -> 2396 -> 3595 -> 5393 -> 8090 -> 12136 -> 18205 -> 27308 -> 40963 -> 61445 -> 92168 -> 138253 -> 207380 -> 311071 -> 466607 -> 699911 -> 1049867 -> 1049867 -> 1 >

最后的收缩

1574801 -> 1234567

更新 2

正如路易斯和克里斯所说,最佳解决方案是

ImmutableList<String> output =
    ImmutableList.copyOf(Lists.transform(input, function));

因为它不包括数组复制。这是因为 Lists.transform 是一个惰性集合并且 ImmutableList.copyOf 查询其大小以分配适当大小的数组。请注意,Iterables.transformFluentIterable 都没有那么高效。

关于java - 用于转换不可变列表的 Guava 单线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19383323/

相关文章:

java - 如何修复: Sudoku solver Stack overflow problem

java - 使用wordnet在java中查找单词的词根

java - 使用二分查找查找 key

java - 自定义 MBean HTML 页面

java - 使用可能返回 null 的函数转换 Guava Optional

java - 从 Web 应用程序遍历部署的文件夹

java - 为什么 Guava Sets::hashCode Impl 有一个带有双补码的奇怪循环更新?

java - Guava 在 Collection View 上的 expireAfterAccess 缓存

list - 代码质量/ Guava : clear and fill a final list or assign a new Immutablelist

java - Spring Framework 5 中 Guava 的支持下降是什么意思?