我想用Stream.allMatch(),但当流空的时候我需要false.

public static void main (String[] args) throws java.lang.Exception
{
   System.out.println(testMethod(Stream.empty())); // <- expected false (but is true)
   System.out.println(testMethod(Stream.of("match", "match"))); // <- expected true
   System.out.println(testMethod(Stream.of("match", "no match"))); // <- expected false
}
    
private static boolean testMethod(Stream<String> stream) {
   return stream.allMatch(text -> "match".equals(text));
}

https://ideone.com/8Nsjiw

我不想用...

我想,我不得不用noMatch(),但我没有得到正确的否定.

private static boolean testMethod(Stream<String> stream) {
   // my guess, but the results are wrong
   return !stream.noneMatch(text -> !"match".equals(text));
}

这不是How to return false for an empty list if using Stream.allMatch()?的副本,因为我使用的是Stream而不是List.


也许是X-Y问题,所以这是我的上层用例

It's about status-collecting. Let's simply this as a download-status indicator for the user. (Not my real use-case, but it is close).
I have a table downloads which looks like this

userId download_name download_status data
1 download 1 loading null
2 download 2 ready 0x4545475

I can't change the tables and I'm limited because it is a huge project (sadly not possible to refactor the world).
Anyways, I want to show the user an indicator about his downloads. The indicator should be only visible, if all downloads are ready. But, if there no downloads yet, then the user should not see the indicator.

我有一个给定的存储库-方法Stream<Downloads> getDownloadsForUser().短路是降低负荷的重要环节.

推荐答案

Java的Stream设计不容易在一次遍历中判断流是否为空and是否所有元素都与给定的谓词匹配.您可以使用局部变量来跟踪计数(但它必须是有效的最终变量,因此您必须使用众所周知的技巧,如1元素数组).这样,您可以保留Stream的短路行为,同时还可以判断流是否为空.

然而,在纯粹的数学/逻辑术语中,将空流视为不包含所有与谓词匹配的元素是没有意义的.这就是vacuous truth的概念.

/**
 * DO NOT USE. This uses the wrong logic: see
 * <a href="https://en.wikipedia.org/wiki/Vacuous_truth#In_computer_programming">vacuous truth</a>.
 */
private static boolean allMatchExceptReturnFalseIfEmpty(Stream<String> stream) {
    boolean[] empty = { true };
    return stream.allMatch(text -> { empty[0] = false; return "match".equals(text); }) && !empty[0];
}

上面的方法将空流视为返回相反结果的特殊值.在许多情况下,在这种情况下采取一些特殊处理可能会更好,如果该方法引发异常,则可以这样做:

/**
 * Better. Checks that all elements match, at the same time checking that the stream is not empty.
 */
private static boolean allMatchNonEmptyStream(Stream<String> stream) {
    boolean[] empty = { true };
    boolean result = stream.allMatch(text -> { empty[0] = false; return "match".equals(text); });
    if (empty[0])
        throw new IllegalArgumentException("Stream must not be empty");
    return result;
}

看待这个问题的另一种方式是,你想要一个三态的结果:

enum MatchResult { EMPTY, ALL_MATCH, SOME_DONT_MATCH }

private static MatchResult allMatchThreeState(Stream<String> stream) {
    boolean[] empty = { true };
    boolean allMatch = stream.allMatch(text -> { empty[0] = false; return "match".equals(text); });
    return (empty[0]) ? MatchResult.EMPTY : allMatch ? MatchResult.ALL_MATCH : MatchResult.SOME_DONT_MATCH;
    
}

在您的例子中(在您的问题更新之后),您可能想要使用这个三态值来显示,例如,(1)无指示器;(2)"正在下载";和(3)"下载完成".即使你现在不想有3个不同的指示器状态,拥有这个3状态的方法结果也会给你更好的灵活性.

Java相关问答推荐

Gmail Javi API批量处理太多请求

将偶数元素移动到数组的前面,同时保持相对顺序

如何为具有多对多关系的实体的给定SQL查询构建JPA规范?

我想了解Java中的模块化.编译我的应用程序时,我有一个ResolutionException

如何调用Firebase Realtime Database中的子图像列表到android studio中的回收器视图?

无法在org. openjfx:javafx—fxml:21的下列变体之间进行 Select

S的字符串表示是双重精确的吗?

Exe4j创建的应用程序无法再固定在任务栏Windows 11上

Com.example.service.QuestionService中的构造函数的参数0需要找不到的类型为';com.example.Dao.QuestionDao;的Bean

Log4j与jdk21兼容吗?

%This内置函数示例

如何在 spring 数据的MongoDB派生查询方法中使用$EXISTS

Java Telnet客户端重复的IAC符号

buildDir:File!&#的getter解决方案是什么?39.被抛弃

有没有办法在o(log(N))中以系统的方式将数组中的小块元素复制和移动到新增长的数组中的左侧?

Java KeyListener不工作或被添加

通过/失败的参数化junit测试方法执行数

具有多个分析模式的复杂分隔字符串的正则表达式

Java System.getProperty在哪里检索user.home?

try 添加;按流派搜索;在Web应用程序上,但没有;I don’我不知道;It’这个代码错了