Soy nuevo en java8 y yo estaba tratando de entender este trozo de código. Este es el fragmento de código:
Stream.of("A", "B", "C").anyMatch(someObj.getStringValue()::equalsIgnoreCase)
someObj.getStringValue()
referencias algún objeto y los getStringValue()
devuelve algún valor de cadena.
Lo que es el predicado equivalente a la referencia al método que se pasa en anyMatch(...)
?
Mi opinión fue que esto sería equivalente a:
Predicate<String> p = new Predicate<String>() {
@Override
public boolean test(String t) {
return someObject.getStringValue().equalsIgnoreCase(t);
}
}
Stream.of("A", "B", "C").anyMatch(p)
Con esto me sale el error "La variable local someObject
definida en un ámbito de inclusión debe ser final o con eficacia final." Cualquier explicación en esta se aprecia.
La someObj.getStringValue()
expresión se evalúa el exterior, por lo que el código equivalente sería:
final String x = someObject.getStringValue();
Predicate<String> p = new Predicate<String>() {
@Override
public boolean test(String t) {
return x.equalsIgnoreCase(t);
}
}
Stream.of("A", "B", "C").anyMatch(p)
donde la variable local x
es "anónimo" también.
Debido a esto, someObject
no es necesario que sea efectiva definitiva .
Puede comprobar este comportamiento para la expresión lambda en un depurador, por poner un punto de interrupción en el interior getStringValue()
. A pesar de que el test()
método se llama 3 veces (porque la corriente tiene 3 elementos, y suponiendo que no hay juego), el getStringValue()
método sólo se llama una vez.