Reputation: 1321
In C# there is a way of reducing the length of an if-statement by using Enumerable.Any
to check if elements in a sequence satisfy a condition (https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx).
For example Instead of:
If ( string.Contains(">") || string.Contains("<") || string.Contains("&") || string.Contains("l") || string.Contains("p") )
We can use
if (new [] { ">", "<", "&", "l", "p"}.Any(w => string.Contains(w)))
Is there an equivalent, if not better, way of doing this in Java?
Upvotes: 28
Views: 4132
Reputation: 97
Looks like org.apache.commons.lang3.StringUtils.containsAny()
does what you want.
Upvotes: 7
Reputation: 1636
If you don't have Java 8, you could just use a regular expression to accomplish your task.
string.matches("^.*?(<|>|p|1|&).*$")
should do the trick.
EDIT:
I wonder which solution performs faster. Eventhough JIT can inline all the lambda goodiness, Stream
(s) might be slower than using a regular expression. I could be completely wrong and I'd appreciate any insight into this from Java 8 stalwarts.
Upvotes: 6
Reputation: 328608
With Java 8 you can write something like:
if (Stream.of(">", "<", "&", "l", "p").anyMatch(string::contains)) {
...
}
Out of curiosity I ran a benchmark to compare this method vs a regex. Code and results below (lower score = faster). Streams perform an order of magnitude better than regex.
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
Code:
@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).*$");
}
}
Upvotes: 26
Reputation: 22641
With Java 8, this is possible with the anyMatch method:
if (Stream.of(">", "<", "&", "l", "p").anyMatch(w -> string.contains(w))) {
}
Upvotes: 9