Lambda expressions are the most significant new features of the Java language since the introduction of generics in Java SE 5, an article in the last installment of the Java magazine in 2012, which describes the design intent, application scenarios, and basic syntax of LAMDBA. (Last updated in 2013.01.07)
Lambda expression, which is selected by the project's Expert group, describes a new functional programming structure that is being eagerly awaited by the new features that will appear in Java SE 8. Sometimes you also hear people using terms such as closures, direct amounts of functions, anonymous functions, and Sam (Single Abstract methods). Some of these terms are slightly different from each other, but basically they all refer to the same function.
Although a lambda expression may seem strange at first, it is easy to grasp. And in order to write applications that fully utilize modern multicore CPUs, it is critical to master lambda expressions.
A key concept to keep in mind is that a lambda expression is a function that is small and can be passed as data. The second concept that needs to be mastered is to understand how the collection object is traversed internally, which is different from the currently existing external sequential traversal.
In this article, we'll show you the motivation behind the lambda expression, the application example, and, of course, its syntax.
Why do you need lambda expressions
There are three main reasons programmers need lambda expressions:
1. More compact Code
2. Ability to modify the functionality of a method by providing additional functionality
3. Better support for multi-core processing
More compact Code
Lambda expressions implement Java classes that have only one method in a concise way.
For example, if you have a large number of anonymous inner classes in your code-such as listeners and processor implementations in UI applications, and callable and runnable implementations in concurrent applications-after using lambda expressions, the code becomes very short and easier to understand.
Ability to modify methods
Sometimes, the method does not have some of the features we want. For example, the contains () method in the collection interface returns true only if the incoming object does exist in the collection object. But we can't interfere with the functionality of the method, for example, if you use a different case scheme to think that the string you are looking for exists in the collection object, we want the contains () method to return true at this point.
To put it simply, what we want to do is "pass our own new code into" the existing method, and then call the incoming code. Lambda expressions provide a good way to represent code that is passed in to existing methods and should be recalled.
Better support for multi-core processing
Today's CPUs have multiple cores. This means that multithreaded routines can actually be executed in parallel, which is completely different from using time sharing in a single core CPU. By supporting functional programming syntax in Java, lambda expressions can help you write simple code to efficiently apply these CPU cores.
For example, you can manipulate large collection objects in parallel, by leveraging parallel programming patterns, such as filtering, mapping, and simplifying (which will soon come in contact with these patterns), to all the available hardware threads in the CPU.
Overview of lambda expressions
In the previous example of finding a string using a different case scheme, what we want to do is to pass the notation of the method toLowerCase () as the second argument to the contains () method, which requires the following work:
1. Find a way to process a code fragment as a value (some sort of object)
2. Find a way to pass the above code fragment to a variable
In other words, we need to wrap a program logic into an object, and that object can be passed on. To be more specific, let's look at the examples of two basic lambda expressions that can be replaced by existing Java code.
Filter
The code snippet you want to pass may be the filter, which is a good example. For example, suppose you are using the Java.io.FileFilter (in the Java SE 7 preview) to determine if the directory is subordinate to a given path, as shown in Listing 1,
Listing 1
File dir = new file ("/an/interesting/location/");
FileFilter directoryfilter = new FileFilter () {public
Boolean accept (file file) {return
file.isdirectory ();
}
};
file[] directories = Dir.listfiles (directoryfilter);
After using a lambda expression, the code is greatly simplified, as shown in Listing 2,
Listing 2
File dir = new file ("/an/interesting/location/");
FileFilter Directoryfilter = (File f)-> f.isdirectory ();
file[] directories = Dir.listfiles (directoryfilter);
The left side of the assignment expression infers the type (FileFilter), and the right looks like a scaled-down version of the Accept () method in the FileFilter interface, which takes a file object and returns a Boolean value after the F.isdirectory () is judged.
In fact, because lambda expressions take advantage of type derivation, we can further simplify the above code based on how it works later. The compiler knows that FileFilter has only one method accept (), so it must be the implementation of the method. We also know that the accept () method requires only one parameter of the file type. Therefore, F must be of type file. As shown in Listing 3,
Listing 3
File dir = new file ("/an/interesting/location/");
file[] directories = Dir.listfiles (f-> f.isdirectory ());
As you can see, using lambda expressions can drastically reduce the number of template code.
Once you get used to using lambda expressions, it makes logical processes very easy to read. One of the key ways to achieve this is to place the filter logic on the side of the method that uses the logic.