java - 如何创建一个新列表并在单个语句中添加一个值

标签 java lambda functional-programming

我想要实现的目标可能毫无意义,但我想找到它来满足我的好奇心。

我正在尝试创建一个单一的高效语句,该语句将基于另一个创建一个新列表并在末尾添加一个新值。

我是 lambda 表达式的新手,我不确定我应该为此使用哪种列表。

该方法看起来像这样:

private List<Integer> conjoin(List<Integer> list, Integer newValue){
    return new ArrayList<Integer>(list).stream()
            .map(value -> list.indexOf(value)==(list.size()-1) ? 
                    Arrays.asList(value, newValue) : 
                    Arrays.asList(value))
            .flatMap(Collection::stream)
            .collect(Collectors.toList());        
}

但更简洁高效。

或者是否有我不知道的内置方法做同样的事情?

最佳答案

我和其他人一样喜欢单行代码,但它们是有代价的——即它们比直白更难读。因此,让我们从“正常”方式开始做您所描述的事情:

ArrayList<E> copy = new ArrayList<>(list);
copy.add(value);
return copy;

虽然只有几行代码,但它高效、直接且易于阅读。我们希望任何替代方案都是对这种语法的改进,而不是为了简洁而简单地取代可读性。如果您试图在已发布的实现和“正常”版本之间做出决定,“正常”版本应该毫无疑问地胜出。


我们可以尝试通过 Stream.concat() 改进您的解决方案和 Stream.of() .

return Stream.concat(list.stream(), Stream.of(value))
    .collect(Collectors.toList());

从技术上讲,现在所有的语句都是一条语句,但我们仍然需要将它分成多行以使其可读。它的样板文件也比标准实现多得多。


相反,我们可以使用构建器模式 Guava提供其 Immutable collections :

return new ImmutableList.Builder<E>().addAll(list).add(value).build();

这样更简洁,并且很好地传达了我们的意图。这就是我建议如何实现您描述的行为(使用 Guava 或定义您自己的 builder pattern )。它不仅适用于这个特定的用例,而且可以扩展到值和集合的任意组合。


认为(很难读懂:))您的示例实际上用您的新值替换列表的最后一个值,而不是将其添加到末尾。如果那是你想要的,只需使用 List.sublist()截断列表中的最后一个元素,例如:

list.sublist(0, list.size() - 1)

在我上面有 list 的任何地方使用它来排除最后一个值。

关于java - 如何创建一个新列表并在单个语句中添加一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32187696/

相关文章:

templates - 如何使用 C++ 模板传递函数及其签名(haskell 样式)?

python - 为 python 中的试错机制寻求更好的设计建议?

functional-programming - mathematica 是函数式编程语言吗?

java - 为什么使用TexturePacker的动画绘制黑色方 block ?

java - java中数字的正则表达式

java - Android 连接 MySQL 数据库失败

c# - Lambda 到表达式树的转换

c++ - Qt 信号 lambda 导致 shared_ptr 泄漏?

java - Weblogic 12c 服务器是否忽略 http.proxy* 参数?

c++ - 使用 lambda 的简单 RAII 包装器的复制初始化在 GCC 和 Clang 下意外失败