我有以下一段代码:
List<Object> list = new ArrayList<>();
list.addAll(method1());
if(list.isEmpty()) { list.addAll(method2()); }
if(list.isEmpty()) { list.addAll(method3()); }
if(list.isEmpty()) { list.addAll(method4()); }
if(list.isEmpty()) { list.addAll(method5()); }
if(list.isEmpty()) { list.addAll(method6()); }
return list;
有没有一种很好的方法可以有条件地添加元素,比如使用流操作?我只想在列表为空时添加method2中的元素,否则返回,以此类推。
编辑:值得一提的是,这些方法包含繁重的逻辑,因此需要防止执行。
一种不重复自己的方法是提取一种为你做的方法:
private void addIfEmpty(List<Object> targetList, Supplier<Collection<?>> supplier) {
if (targetList.isEmpty()) {
targetList.addAll(supplier.get());
}
}
然后
List<Object> list = new ArrayList<>();
addIfEmpty(list, this::method1);
addIfEmpty(list, this::method2);
addIfEmpty(list, this::method3);
addIfEmpty(list, this::method4);
addIfEmpty(list, this::method5);
addIfEmpty(list, this::method6);
return list;
或者甚至使用for循环:
List<Supplier<Collection<?>>> suppliers = Arrays.asList(this::method1, this::method2, ...);
List<Object> list = new ArrayList<>();
suppliers.forEach(supplier -> this.addIfEmpty(list, supplier));
现在干燥不是最重要的方面。如果您认为您的原始代码更易于阅读和理解,请保持这样。
我会简单地使用供应商流并过滤List.isEmpty
:
Stream.<Supplier<List<Object>>>of(() -> method1(),
() -> method2(),
() -> method3(),
() -> method4(),
() -> method5(),
() -> method6())
.map(Supplier<List<Object>>::get)
.filter(l -> !l.isEmpty())
.findFirst()
.ifPresent(list::addAll);
return list;
findFirst()
将防止在其中一个方法返回第一个非空列表时对方法N()
的不必要调用。
编辑:
如下面的评论中所述,如果您的列表
对象未使用其他任何内容初始化,则直接返回流的结果是有意义的:
return Stream.<Supplier<List<Object>>>of(() -> method1(),
() -> method2(),
() -> method3(),
() -> method4(),
() -> method5(),
() -> method6())
.map(Supplier<List<Object>>::get)
.filter(l -> !l.isEmpty())
.findFirst()
.orElseGet(ArrayList::new);
您可以尝试检查 addAll
的返回值。每当列表被修改时,它将返回 true
,因此请尝试以下操作:
List<Object> list = new ArrayList<>();
// ret unused, otherwise it doesn't compile
boolean ret = list.addAll(method1())
|| list.addAll(method2())
|| list.addAll(method3())
|| list.addAll(method4())
|| list.addAll(method5())
|| list.addAll(method6());
return list;
由于惰性求值,第一个添加至少一个元素的 addAll
操作将阻止其余元素被调用。我喜欢“||”很好地表达了意图。
正如这篇stackoverflow文章中所述,在调用终端操作之前,不会实际应用筛选器。既然我在调用终端操作之前重新分配了stream的值,那么上面的代码是否仍然是使用Java8流的适当方法呢?
问题内容: 是否可以根据条件向标签添加内容?像在此示例中一样,当我只想在第一次迭代中添加时(仅用于的第一个元素)? 问题答案: 是的,在这种情况下,AngularJS具有两个指令: 可以使用ng-show / ng-hide指令族基于评估表达式的结果来隐藏(通过使用显示CSS规则)DOM 3的一部分。 如果我们想有条件地物理删除/添加DOM的一部分,那么ng-switch指令家族(ng-switc
本文向大家介绍aurelia 有条件地添加或删除HTML元素,包括了aurelia 有条件地添加或删除HTML元素的使用技巧和注意事项,需要的朋友参考一下 示例 与show.bind使用时不同,if.bind如果提供的绑定值是,则元素将从页面中删除;如果值为,则将元素false添加到页面中true。 分组元素 有时可能需要一次性添加或删除整组元素。为此,我们可以使用<template>元素来显示或
问题内容: Collector的Javadoc显示了如何将流的元素收集到新的List中。有没有一种将结果添加到现有ArrayList中的方法? 问题答案: 注意: osid的答案 显示了如何使用来添加到现有集合。这是对现有集合进行变异的有用且有效的技术。我的答案解决了为什么您不应该使用A 来突变现有集合的原因。 简短的答案是 no ,至少在一般情况下不是这样,您不应该使用a 来修改现有集合。 原因
Collector的Javadoc展示了如何将流的元素收集到一个新列表中。是否有一个单行程序将结果添加到现有的ArrayList中?
我有问题动态添加jsx表行到表中的反应。 我的案例如下: 如果表行包含子行,请将它们添加到主行之外。 这是我最初的设计: 问题是不允许div作为tbody标记中的子级。你知道我怎样才能不把我的报税单写进div里就解决这个问题吗? 我在考虑将整个tbody移动到我的行组件,并有条件地在那里渲染子行,但是我看不出这有什么帮助,因为我仍然不能在返回周围使用任何包装器...我唯一能使用的包装器是tbody