我想要实现的目标可能毫无意义,但我想找到它来满足我的好奇心。
我正在尝试创建一个单一的高效语句,该语句将基于另一个创建一个新列表并在末尾添加一个新值。
我是 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/