ejemplo - substring from character java
Java equivalente de C#''Enumerable.Any'' (4)
Con Java 8 puedes escribir algo como:
if (Stream.of(">", "<", "&", "l", "p").anyMatch(string::contains)) {
...
}
Por curiosidad, ejecuté un punto de referencia para comparar este método frente a una expresión regular. Código y resultados a continuación (puntaje más bajo = más rápido). Los flujos realizan un orden de magnitud mejor que el 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
Código:
@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).*$");
}
}
En C # hay una forma de reducir la longitud de un enunciado if mediante el uso de Enumerable.Any
para verificar si los elementos de una secuencia satisfacen una condición ( https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx ).
Por ejemplo, en lugar de:
If ( string.Contains(">") || string.Contains("<") || string.Contains("&") || string.Contains("l") || string.Contains("p") )
Nosotros podemos usar
if (new [] { ">", "<", "&", "l", "p"}.Any(w => string.Contains(w)))
¿Hay una forma equivalente, si no mejor, de hacer esto en Java?
Con Java 8, esto es posible con el método anyMatch :
if (Stream.of(">", "<", "&", "l", "p").anyMatch(w -> string.contains(w))) {
}
Parece que org.apache.commons.lang3.StringUtils.containsAny()
hace lo que quiere.
Si no tiene Java 8, puede usar una expresión regular para realizar su tarea.
string.matches("^.*?(<|>|p|1|&).*$")
debería hacer el truco.
EDITAR:
Me pregunto qué solución funciona más rápido. Aunque JIT puede alinear toda la bondad lambda, Stream
(s) podría ser más lento que usar una expresión regular. Podría estar completamente equivocado y agradecería cualquier idea sobre esto de los incondicionales de Java 8.