from ejemplo java if-statement string-search

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))) { }



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.