我想创建一个列表的CompletableFuture
。对于任何失败的元素,我想在单独的列表中收集失败的元素(用于进一步处理)。
问题:'错误集合'必须为final
才能在lambda表达式中添加元素。
但大多数时候,我没有任何例外,因此列表的实例化是没用的。
//just an example list to illustrate
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> errors = null; //non final
List<CompletableFuture<Integer>> futures =
list.stream()
.map(i -> CompletableFuture.supplyAsync(
() -> {
if (i % 2 == 0) throw new RuntimeException(i); //dummy business logic exception
return i;
})
.exceptionally(ex -> {
if (errors == null) errors = new ArrayList<>(); //TODO: invalid as written
errors.add(i);//TODO: invalid as written
return null;
})
)
.collect(Collectors.toList());
问题:这有可能吗?
答案 0 :(得分:1)
解决方案解决方案:您是否也可以将初始List<Integer>
用作 errorsList ?
从List
中删除所有符合您业务条件的元素。
List<CompletableFuture<Integer>> futures = list.stream()
.map(i -> CompletableFuture.supplyAsync( () -> {
synchronized (list) {
// not a dummy business error
if (i % 2 != 0) {
list.remove(i);
}
}
return i;
})).collect(Collectors.toList());
最后,list
将仅包含错误。并且你不会再有一个空的未使用的Collection
,这会让你烦恼。
请注意,它不会与Arrays.asList(T...);
一起使用,因为它会返回一个java.util.Arrays.ArrayList
实例,该实例是不可修改的。
我个人不喜欢这个解决方案:
synchronized
阻止synchronized
阻止
List
Iterator
中的元素
答案 1 :(得分:0)
我能让它工作的唯一方法是使错误列表成为一个私有的静态ArrayList,它将Objects作为元素。走这条路意味着很多被压制的警告。通过这样做,我能够在错误列表中获得2和4。我希望这有帮助!
public class Main {
private static ArrayList<Object> errors;
public static void main(String[] args) {
//just an example list to illustrate
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<CompletableFuture<Integer>> futures =
list.stream()
.map(i -> CompletableFuture.supplyAsync(
() -> {
if (i % 2 == 0) throw new RuntimeException(i.toString()); //dummy business logic exception
return i;
})
.exceptionally(ex -> {
if (errors == null) errors = new ArrayList<>();
errors.add(i);
return null;
})
)
.collect(Collectors.toList());
System.out.println(errors);
}
}
答案 2 :(得分:0)
我找到了使用BiConsumer
的方法:
BiConsumer<Throwable, Integer> handler = new BiConsumer<Throwable, Integer>() {
List<Integer> errors;
@Override
public void accept(Throwable throwable, Integer i) {
if (errors == null) errors = new ArrayList<>();
errors.add(i);
}
public List<Integer> getErrors() {
return errors;
}
};
流中的用法:
...
.exceptionally(ex -> {
handler.accept(ex, i);
return null;
})
答案 3 :(得分:-1)
你可以用一种方法来做到这一点。
List<CompletableFuture<Integer>> futures =
list.stream()
.map(i -> yourFunction(i)).(Collectors.toList());
...
public CompletableFuture<Integer> yourFunction(CompletableFuture<Integer> i){
...
}
这不是很多练习但是有效