18

我正在尝试确定List使用即将发布的Java 8中的新 lambdas 功能更改所有值的正确方法,而无需创建**new** List.

这与List调用者传入 a 并且需要应用函数以将所有内容更改为新值的时间有关。例如,Collections.sort(list)就地更改列表的方式。

给定这个转换函数和这个起始列表,将函数应用于原始列表中的所有值而不创建新列表的最简单方法是什么?

String function(String s){ 
    return s.toUppercase(); // or something else more complex
}

List<String> list = Arrays.asList("Bob", "Steve", "Jim", "Arbby");

将更改应用到所有值的通常方法是:

for (int i = 0; i < list.size(); i++) {
    list.set(i, function( list.get(i) );
}

lambdas 和 Java 8 是否提供:

  • 更简单、更有表现力的方式?
  • 一种无需设置所有for(..)循环脚手架的方法吗?
4

3 回答 3

33
    List<String> list = Arrays.asList("Bob", "Steve", "Jim", "Arbby");
    list.replaceAll(String::toUpperCase);
于 2013-10-31T15:04:11.070 回答
2

使用流行的库Guava,您可以在不为新数组分配内存的列表上创建计算视图,即:

upperCaseStrings = Lists.transform(strings, String::toUpperCase)

@StuartMarks 提出了一个更好的解决方案,但是,我将留下这个答案,因为它还允许更改集合的通用类型。


另一种选择是声明一个静态方法,例如mutate将 list 和 lambda 作为参数,并将其作为静态方法导入,即:


mutate(strings, String::toUpperCase);

一个可能的实现mutate

@SuppressWarnings({"未选中"})
public static List mutate(List list, Function function) {
    列表 objList = 列表;

    对于 (int i = 0; 我

于 2013-10-31T08:58:36.843 回答
-1

你似乎忽略了forEach,它可以用来改变 a 的元素List。当然,这并没有完全涵盖您的用例——如果您的元素是不可变的或者如果您想完全替换它们,这将无济于事。[编辑:下一句与流有关,而不是问题中指定的集合]您不能执行这些操作是有充分理由的:它们不是并行友好的(这实际上也适用于forEach)和 Stream API 强烈反对使用仅顺序操作。

于 2013-10-31T10:01:10.120 回答