I've talked about what types functional interfaces take and mentioned that javac can auto-
matically infer the types of parameters and that you can manually provide them, but when do
you know whether to provide them? Let's look a bit more at the details of type inference.
There are certain circumstances in which you need to manually provide type hints, and my
advice is to do what you and your team find easiest to read. Sometimes leaving out the types
removes line noise and makes it easier to see what is going on. Sometimes leaving them in
can make it clearer what is going on. I've found that at first they can sometimes be helpful,
but over time you'll switch to adding them in only when they are actually needed. You can
figure out whether they are needed from a few simple rules that I'll introduce in this chapter.
The type inference used in lambdas is actually an extension of the target type inference intro-
duced in Java 7. You might be familiar with Java 7 allowing you to use a diamond operator
Example 2-9. Diamond inference for variables
Map < String , Integer > oldWordCounts = new
new HashMap < String , Integer >();
Map < String , Integer > diamondWordCounts = new
new HashMap <>();
For the variable oldWordCounts we have explicitly added the generic types, but dia-
mondWordCounts uses the diamond operator. The generic types aren't written out—the
compiler just figures out what you want to do by itself. Magic!
It's not really magic, of course. Here, the generic types to HashMap can be inferred from the
type of diamondWordCounts . You still need to provide generic types on the variable that
is being assigned to, though.
If you're passing the constructor straight into a method, it's also possible to infer the generic
types from that method. In Example 2-10 , we pass a HashMap as an argument that already
has the generic types on it.
Example 2-10. Diamond inference for methods
useHashmap ( new
new HashMap <>());
void useHashmap ( Map < String , String > values );