2015-06-19 74 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,任何時間! –