2015-06-19 73 views
24

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

例如相反的:

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

我们可以使用

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

是否有一个等价的,如果没有更好的,在Java这样的方式?

+1

只是为了完整性:您也可以在C#中使用'.Any(string.Contains)'而不是更详细的'.Any(w => string.Contains(w))''。 – Bob

回答

23

与Java 8,你可以写这样的:

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

出于好奇,我跑了一个基准来比较这个方法VS正则表达式。下面的代码和结果(更低的分数=更快)。流比正则表达式执行的数量级要好。

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).*$"); 
    } 
} 
+0

@MarcoAcierno String ::包含引用一个不存在的静态方法。 https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html – Ezequiel

+2

我的不好,我删除了评论。我错过了'string'是一个变量 –

+0

感谢澄清。我想知道Regex是否会更快地检查子字符串而不是单个字符。我不确定在这些情况下'contains()'是否表现良好。 –

9

使用Java 8,这是可能的anyMatch方法:

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

} 
6

如果您没有安装Java 8,你可以只使用一个普通表达来完成你的任务。

string.matches("^.*?(<|>|p|1|&).*$")应该做的伎俩。

编辑:

我不知道哪解决方案执行速度更快。尽管JIT可以内联所有的lambda好,但是Stream(s)可能比使用正则表达式要慢。我可能是完全错误的,我很感谢来自Java 8 stalwarts的任何洞察。

+0

谢谢!这工作完美。 – Mirodinho

+1

@ Amrito10,任何时间! –