首页 > 解决方案 > Java Lambda for break 在两个 for 循环中

问题描述

我正在尝试将 Java 8 中的迭代代码块转换为函数式。函数式方法无法在共享集中找到匹配的消息。

List<Optional<Message>> allMessages = new ArrayList<>();

Set<Status> allStatuses = getAllStatuses();

//Iterative : Working
Set<StatusMessage> set = new HashSet<>(STATUS_MESSAGE.values());
for (StatusMessage statusMessage : set) {
    for (Status status : statusMessage.getStatusAndInfo().keySet()) {
        Optional<Message> message = MessageBuilder.createMessage(allStatuses, status, this::createMessage);
        if (message.isPresent()) {
            allMessages.add(message);
            break;
        }
    }
}

//Functional : Not working  - Never adds anything to the 
//map even when matching status is present
STATUS_MESSAGE.values().stream()
        .distinct()
        .map(statusMessage -> statusMessage.getStatusAndInfo().keySet())
        .flatMap(Collection::stream)
        .map(key -> MessageBuilder.createMessage(allStatuses, key, this::createMessage))
        .anyMatch(allMessages::add);

MessageBuilder.createMessage看起来像这样:

Optional<Status> matchingStatus = statuses.stream()
                .filter(matchingStatus::equals)
                .findFirst();
System.out.println("Found : " + matchingStatus.toString());
return matchingStatus.flatMap(creator);

此外,出于调试目的,我如何查看流的每个步骤发生了什么?intellij 调试器中的堆栈在流中没有显示任何内容。

标签: javacollectionsjava-8functional-programmingjava-stream

解决方案


这应该这样做:

STATUS_MESSAGE.values().stream()
        .distinct()
        .forEach(statusMessage ->
            statusMessage.getStatusAndInfo().keySet().stream()
                    .map(status -> MessageBuilder.createMessage(allStatuses, status, this::createMessage))
                    .filter(Optional::isPresent)
                    .findFirst()
                    .ifPresent(allMessages::add)
        );

更新

toList要使用而不是添加到列表来构建结果列表:

List<Optional<Message>> allMessages = STATUS_MESSAGE.values().stream()
        .distinct()
        .flatMap(statusMessage ->
            statusMessage.getStatusAndInfo().keySet().stream()
                    .map(status -> MessageBuilder.createMessage(allStatuses, status, this::createMessage))
                    .filter(Optional::isPresent)
                    .limit(1)
        )
        .collect(Collectors.toList());

推荐阅读