Java Reference
In-Depth Information
17.3.1 Creating an IntStream and Displaying Its Values with the
forEach Terminal Operation
IntStream static method of (line 14) receives an int array as an argument and returns
an IntStream for processing the array's values. Once you create a stream, you can chain
together multiple method calls to create a stream pipeline . The statement in lines 14-15
creates an IntStream for the values array, then uses IntStream method forEach (a
terminal operation) to perform a task on each stream element. Method forEach receives
as its argument an object that implements the IntConsumer functional interface (package
java.util.function )—this is an int -specific version of the generic Consumer functional
interface. This interface's accept method receives one int value and performs a task with
it—in this case, displaying the value and a space. Prior to Java SE 8, you'd typically imple-
ment interface IntConsumer using an anonymous inner class like:
new IntConsumer()
{
public void accept( int value)
{
System.out.printf( "%d " , value);
}
}
but in Java SE 8, you simply write the lambda
value -> System.out.printf( "%d " , value)
The accept method's parameter name ( value ) becomes the lambda's parameter, and the
accept method's body statement becomes the lambda expression's body. As you can see,
the lambda syntax is clearer and more concise than the anonymous inner class.
Type Inference and a Lambda's Target Type
The Java compiler can usually infer the types of a lambda's parameters and the type re-
turned by a lambda from the context in which the lambda is used. This is determined by
the lambda's target type —the functional interface type that is expected where the lambda
appears in the code. In line 15, the target type is IntConsumer . In this case, the lambda
parameter's type is inferred to be int , because interface IntConsumer 's accept method ex-
pects to receive an int . You can explicitly declare the parameter's type, as in:
( int value) -> System.out.printf( "%d " , value)
When doing so, the lambda's parameter list must be enclosed in parentheses. We generally
let the compiler infer the lambda parameter's type in our examples.
final Local Variables, Effectively final Local Variables and Capturing Lambdas
Prior to Java SE 8, when implementing an anonymous inner class, you could use local vari-
ables from the enclosing method (known as the lexical scope ), but you were required to
declare those local variables final . Lambdas may also use final local variables. In Java SE
8, anonymous inner classes and lambdas can also use effectively final local variables —that
is, local variables that are not modified after they're initially declared and initialized. A lamb-
da that refers to a local variable in the enclosing lexical scope is known as a capturing lamb-
da . The compiler captures the local variable's value and ensures that the value can be used
when the lambda eventually executes, which may be after its lexical scope no longer exists .
 
 
Search WWH ::




Custom Search