Java相当于C#的'Enumerable.Any'

时间:2015-06-19 14:28:13

标签: java if-statement string-search

在C#中,有一种方法可以通过使用Enumerable.Any来检查序列中的元素是否满足条件(https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx)来减少if语句的长度。

例如,而不是:

If ( string.Contains(">") || string.Contains("<") || string.Contains("&") || string.Contains("l") || string.Contains("p") )

我们可以使用

if (new [] { ">", "<", "&", "l", "p"}.Any(w => string.Contains(w)))

在Java中是否有相同的,甚至更好的方法?

4 个答案:

答案 0 :(得分:26)

使用Java 8,您可以编写如下内容:

if (Stream.of(">", "<", "&", "l", "p").anyMatch(string::contains)) {
  ...
}

出于好奇,我运行了一个基准来比较这个方法和一个正则表达式。下面的代码和结果(分数越低=越快)。 Streams的性能比正则表达式要好一些。

Benchmark                                    (s)  Mode  Samples     Score    Error  Units
c.a.p.SO30940682.stream   >aaaaaaaaaaaaaaaaaaaaa  avgt       10    49.942 ±  1.936  ns/op
c.a.p.SO30940682.stream   aaaaaaaaaaaaaaaaaaaaa>  avgt       10    54.263 ±  1.927  ns/op
c.a.p.SO30940682.stream   aaaaaaaaaaaaaaaaaaaaap  avgt       10   131.537 ±  4.908  ns/op
c.a.p.SO30940682.stream   paaaaaaaaaaaaaaaaaaaaa  avgt       10   129.528 ±  7.352  ns/op
c.a.p.SO30940682.regex    >aaaaaaaaaaaaaaaaaaaaa  avgt       10   649.867 ± 27.142  ns/op
c.a.p.SO30940682.regex    aaaaaaaaaaaaaaaaaaaaa>  avgt       10  1047.122 ± 89.230  ns/op
c.a.p.SO30940682.regex    aaaaaaaaaaaaaaaaaaaaap  avgt       10  1029.710 ± 61.055  ns/op
c.a.p.SO30940682.regex    paaaaaaaaaaaaaaaaaaaaa  avgt       10   694.309 ± 32.675  ns/op

代码:

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
public class SO30940682 {

  @Param({">aaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaa>",
          "aaaaaaaaaaaaaaaaaaaaap", "paaaaaaaaaaaaaaaaaaaaa"}) String s;

  @Benchmark public boolean stream() {
    return Stream.of(">", "<", "&", "l", "p").anyMatch(s::contains);
  }

  @Benchmark public boolean regex() {
    return s.matches("^.*?(>|<|&|l|p).*$");
  }
}

答案 1 :(得分:9)

使用Java 8,可以使用anyMatch方法:

if (Stream.of(">", "<", "&", "l", "p").anyMatch(w -> string.contains(w))) {

}

答案 2 :(得分:7)

看起来org.apache.commons.lang3.StringUtils.containsAny()可以满足您的需求。

答案 3 :(得分:6)

如果您没有Java 8,则可以使用正则表达式来完成任务。

string.matches("^.*?(<|>|p|1|&).*$")应该可以解决问题。

修改

我想知道哪种解决方案表现得更快。虽然JIT可以内联所有lambda goodiness,Stream(s)可能比使用正则表达式慢。我可能完全错了,我很欣赏Java 8 stalwarts对此的任何见解。