我收到带有消息标题的消息。请参阅下面的示例消息
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 根本无法实现吗?
您仍然可以检查字符串是否以“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
更好。