读取 if string.startsWith() 并在条件失败时停止流

问题描述 投票:0回答:1

我收到带有消息标题的消息。请参阅下面的示例消息

private static String sampleMessage() {
        return """
               message from arunmantics.com
               X-Origination-IP:19.1.1.1.1
               X-api-kEY=134SDGFSDG234234SDFSDF
               Your order 6798977 is delivered.
               This order's cost is 
               """;
    }

只有当它以

message from arunmantics.com
开头时,我才必须处理这个字符串。我能够以命令式的方式实现这一点。请参阅下面的示例代码

public static void main(String[] args) {
        String message = sampleMessage();

        StringBuilder sb = new StringBuilder();

        if (message.startsWith("message from arunmantics.com")) {
            var beginIndex = message.indexOf("com")+3;
            message = message.substring(beginIndex,message.length());


            for (String currentLine : message.split(System.lineSeparator())) {
                if (!currentLine.startsWith("X-")) {
                    sb.append(currentLine);
                }
            }
        }

        System.out.println(sb);

    }

但我想摆脱这种命令式编码风格,转向函数式风格。

我想做这样的事情

message.lines()
       .filter(...)

但如果不是以

message from arunmantics.com
开始,我不能完全决定停止流。

我使用了

findFirst()
,但正如预期的那样,它给了我一个仅包含该特定字符串的 Optional 并过滤掉其余的字符串。

使用 Streams API 根本无法实现吗?

java java-stream functional-interface
1个回答
0
投票

您仍然可以检查字符串是否以“message from arunmantics.com”开头,与之前一样。它没有任何“非功能性”。

我希望将它作为流管道的一部分

如果你真的想把它作为一个链来做,你可以在技术上创建一个单例流,如果消息不是以“来自arunmantics.com的消息”开头,则使用

filter
实质上创建一个空流,并且然后
flatMap
lines
.

var result = Stream.of(message)
    .filter(s -> s.startsWith("message from arunmantics.com"))
    // the above creates an empty stream if the condition is false
    // and everything below will effectively do nothing, and the result will be an empty string
    .flatMap(String::lines)
    .skip(1) // skips the "message from..." line
    .filter(x -> !x.startsWith("X-"))
    .collect(Collectors.joining());

这真的没有像使用

if
那样清楚地显示意图,而且在我看来,它真的不比使用
if
更好。

© www.soinside.com 2019 - 2024. All rights reserved.