如果map中的任何值为空字符串或仅为空格,则在Java8中返回false。

4

我将尝试写一行代码,如果map中的任何值为空字符串或空格字符串,则返回false。有何想法?

类似于以下高级版本:

 Optional.ofNullable(map).filter(s -> s.isEmpty());
3个回答

4

使用您目前的方法:

boolean present = 
        Optional.ofNullable(map)
                .filter(x -> 
                        x.values().stream()
                                  .noneMatch(s -> s != null && s.trim().isEmpty()))
                                  .isPresent();

或者简单地说:
boolean present = map != null && 
                  map.values()
                     .stream()
                     .noneMatch(s -> s != null && s.trim().isEmpty());

2
在“更简单”的情况下,s != null && s.isEmpty() ||是多余的。如果字符串为空,则trim()返回相同的字符串。但是在第二种情况下,s.trim().isEmpty()更加整洁。 - Andy Turner
@AndyTurner 对不起,我没有仔细阅读文档。我以为s.trim()总是会构造一个新的字符串对象,因此在调用它之前进行了检查。尽管如此,你是正确的,我已经修改了。感谢 :). - Ousmane D.
2
离题:不知道你是否还记得那个关于 b ? Integer.valueOf(0) : Long.valueOf(0) 的问题,导致了有趣的类型?我为此编写了一个 Error Prone 检查 - 并且实际上在 openjdk 中发现了一个 bug!我提到这件事是因为我记得你曾经评论过这个问题非常奇怪。 - Andy Turner

3

如果你只是想检查空字符串是否存在,可以使用以下方法:

public static boolean containsNoEmptyString(Map<?,?> map) {
    return !map.containsValue("");
}

如果您想检查空字符串,我建议使用:
public static boolean containsNoBlankString(Map<?,String> map) {
    return map.values().stream().noneMatch(Pattern.compile("^\\s*$").asPredicate());
}

s.trim().isEmpty() 这样的操作不仅检查所需的属性,而且还会构造一个新字符串。创建新对象本身并不是问题,即正则表达式匹配操作也可能在幕后创建对象,但是 trim() 操作创建字符串存在潜在的昂贵操作,其开销随输入字符串的大小而变化。
空字符串或空白字符串没有问题,因为应用 trim() 只会返回一个廉价的空字符串。同样,如果字符串不以空格开始或结束,则 trim() 只会返回原始字符串。
问题在于可能有不是空白的字符串,但以空格开始或结束。然后,trim() 将创建一个新字符串,并复制整个字符串,除了前导和尾随空格,这可能是任意数量的字符。因此,这种操作的潜在成本,在性能和内存方面都会随着字符串的大小而增加。
相比之下,正则表达式匹配操作的开销是固定的。只有实际匹配依赖于字符串的长度,但即使在那里,正则表达式匹配操作也更便宜。 trim() 在开头搜索空格,并在识别第一个非空格字符后搜索字符串末尾的空格,以剥离两者。正则表达式匹配将从开头开始,但在第一个非空格字符处停止,因为此时字符串不为空白。只有对于真正的空白字符串,成本才会相当,但最多只会检查一个空白字符串的映射,因为这是停止条件,在检查任意数量的非空白字符串后达到该条件。

1
这是关于正则表达式“非常”耗费资源的又一个神话吗?每次我在工作中使用它时,都会在代码审查中收到这样的评论,认为它很耗费资源,并且需要编写正确且良好的基准测试来证明其它方面... - Eugene
@Eugene,有一个简单的经验法则。如果您将执行相同的匹配操作多次,则额外的准备开销很可能会在之后得到回报。如有疑问,您可以重构代码以将预编译的“Pattern”保留在“static”变量中。然后,在正则表达式内部进行纯字符比较时,与纯“String”操作相比,没有理由为什么速度应该更慢。但即使是对于字面文本搜索,准备工作也可能会在进行匹配时得到回报 - Holger
这已经是我第二次观看关于Boyer Moore的视频了(至少YouTube这样说),我猜这还是你指引我的...谢谢你,现在我在评论中有了一个好的论据! - Eugene
@Eugene 实际上,应该反过来。如果你的同事声称你的代码很慢(由于使用正则表达式或其他原因),那么他们应该负责证明。甚至可能有一种特定的正则表达式引擎使用确实比另一种更慢,但只是在可以忽略不计的范围内。避免使用它的唯一理由应该是当基准测试/分析证明真的存在由正则表达式引擎引起的性能问题时。正如前面所说,即使在这种情况下,也应该检查是准备工作还是低效模式导致了问题,因为两者都可以解决... - Holger
1
我的意思是,两者都可以在不停止使用正则表达式引擎的情况下修复。 - Holger
好的观点,谢谢你。不幸的是,在我目前所在的地方这永远不会发生,但这仍然是一个潜在搬到新地方时值得问的好问题。 - Eugene

3
如何考虑:
return map.values().stream().noneMatch(v -> v != null && v.trim().isEmpty());

v.trim().isEmpty()是当字符串为空("")或仅包含空格时返回true。

noneMatch是当流中的所有项(这里是值)都不满足谓词时返回true。由于它是短路运算,因此它非常高效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接