我想要实现的目标可能毫无意义,但我想找到这个以满足我的好奇心。
我正在尝试创建一个单独的高效语句,该语句将基于另一个创建新列表并在末尾添加新值。
我是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());
}
但更整洁有效。
或者是否存在我不知道的内置方法?
答案 0 :(得分:3)
我和其他人一样喜欢单行,但是他们付出了代价 - 也就是说,他们比阅读更难以阅读。所以让我们从“正常”的方式开始,做你正在描述的事情:
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
的任何地方使用它来排除最后一个值。
答案 1 :(得分:1)
一个选项是使用
List<Integer> newList = (List<Integer>)ListUtils.union(list1,Arrays.asList(5));
来自Apache Commons Collections。我知道在内部这不是一个单一的陈述,而是那个有用的图书馆,很多人都有可能拥有它。
实施例
// Your list
ArrayList<Integer> myList = new ArrayList<Integer>();
myList.add(2);
// Create new list with new element
List<Integer> newList = (List<Integer>)ListUtils.union(myList,Arrays.asList(5));
答案 2 :(得分:0)
你可以试试这个
private List<Integer> conjoin(List<Integer> list, final Integer newValue){
ArrayList<Integer> returnlist = new ArrayList<Integer>(list) {{
add(newValue);
}};
return returnlist;
}