The first time that a contact lambda expression is in typescript (the hyper-concentration of JavaScript) is to let the typescript this method be used outside of this method. After use, does it suddenly occur to you that a lambda is not a new heavyweight feature of JDK8? So the feeling of access to the relevant information and recorded:
I. Behavioral parameterization
Behavior parameterization simply means that the body of the function contains only the generic code of the template class, and some logic that changes with the business scene is passed into the function as a parameter, using behavioral parameterization to make the program more versatile to cope with the need for frequent changes.
Consider a business scenario, assuming we need to sift through the app, we first define an Apple entity:
public class Apple {
/** number *
/private long ID;
/** color *
/private color color;
/** Weight * *
private float weight;
/** Origin * *
private String origin;
Public Apple () {
} public
Apple (long ID, color color, float weight, String origin) {
this.id = ID;
This.color = color;
This.weight = weight;
This.origin = origin;
}
Omit getter and Setter
}
The user's initial needs may be simply a desire to filter out the green Apple through the program, so we can quickly implement the program:
public static list<apple> filtergreenapples (list<apple> apples) {
list<apple> filterapples = new Arraylist<> ();
For (final Apple apple:apples) {
if (Color.GREEN.equals (Apple.getcolor ())) {
filterapples.add (Apple);
}
}
return filterapples;
}
This code is very simple, there is nothing worth saying. But when the user needs to become green, it looks like the code is also very simple to change the conditions of the green to red. But we need to consider another question, what if changing conditions are changing so frequently? If it's just a change in color, then we let the user pass the judgement of the color directly, and judge the parameter of the method as "the set of judgment and the color to be filtered". But if the user is not only judge color, but also want to judge weight, size ah what, how to do? Do you think we can do this by adding different parameters in turn? But is it really good to pass the arguments in such a way? If the filter becomes more and more complex, do we need to consider all the circumstances and have a corresponding strategy for each situation? At this point we can parameterize the behavior, filter the conditions, and pass it out as parameters, at which point we can encapsulate a judged interface:
Public interface Applefilter {
/**
* Filter Criteria Abstract
*
* @param Apple
* @return
/Boolean Accept ( Apple apple);
/**
* Encapsulates filter criteria as interface
* *
@param apples
* @param filter * @return/public
static List <Apple> filterapplesbyapplefilter (list<apple> apples, Applefilter filter) {
list<apple> Filterapples = new arraylist<> ();
For (final Apple apple:apples) {
if (filter.accept (apple)) {
filterapples.add (Apple);
}
}
return filterapples;
}
After the above behavior is abstracted, we can set the filter criteria where the call is made and pass the condition as a parameter to the method, using the method of the anonymous inner class:
public static void Main (string[] args) {
list<apple> apples = new arraylist<> ();
Filter Apple
list<apple> filterapples = Filterapplesbyapplefilter (apples, new Applefilter () {
@Override Public
Boolean Accept (Apple) {
//filter Red apple with weight greater than 100g return
Color.RED.equals (Apple.getcolor ()) && apple.getweight () > ()
}
);
This design is often used within the JDK, such as java.util.comparator,java.util.concurrent.callable, and so on, when using this kind of interface, we can use anonymous class to specify the specific execution logic of the function in the place where the specific call is made, but from the above code block, although very geek, but not concise enough, In Java8 we can simplify by lambda:
Filter Apple
list<apple> filterapples = Filterapplesbyapplefilter (apples, apple apple
)-> Color.RED.equals (Apple.getcolor ()) && apple.getweight () >=);
()->xxx () is the method parameter, XXX is the method implementation
Two. Lambda expression definition
We can define a lambda expression as a concise, transitive anonymous function, and first we need to be clear that a lambda expression is essentially a function, although it does not belong to a particular class, but has a list of arguments, a function body, a return type, and the ability to throw an exception; Lambda expressions do not have specific function names; Lambda expressions can be passed like parameters, making it much easier to write code. The format is defined as follows:
Format one: parameter list-> expression
Format two: parameter list-> {expression Collection}
It is to be noted that lambda expressions implicitly imply the return keyword, so in a single expression we do not need to explicitly write the return keyword, but when an expression is a collection of statements, you need to explicitly add a return and surround the expressions with curly braces {}. Let's look at a few examples:
Returns the length of the given string, the implied return statement
(string s)-> s.length ()
///The parameterless method () that always returns 42
()->
//contains multiple rows of expressions, enclosed in curly braces
(int x, int y)-> {
int z = x * y;
return x + z;
}
Three. Using lambda expressions based on functional interfaces
The use of lambda expressions requires a functional interface, which means that only functional interfaces appear where they can be simplified using lambda expressions.
Custom Function-Interface:
Functional interfaces are defined as interfaces that have only one abstract method. JAVA8 's improvement in interface definition is the introduction of the default method, which allows us to provide a default implementation of the method in the interface, but no matter how many default methods exist, as long as there is one and only one abstract method, it is a functional interface, as follows (refer to the above applefilter):
/**
* Apple Filter Interface * *
@FunctionalInterface Public
interface Applefilter {
/**
* Filter Criteria Abstract
*
@param apple
* @return
/Boolean accept (Apple);
Applefilter contains only an abstract method accept (Apple), which can be treated as a functional interface by definition, where we add a @functionalinterface annotation for the interface to mark the interface as a functional interface. However, this interface is optional, and when the interface is added, the compiler restricts the interface to only one abstract method, or an error, so it is recommended that the annotation be added to the functional interface.
A functional interface with JDK:
The JDK has a rich functional interface built into lambda expressions, and the following are illustrated with examples of the use of predicate<t>, consumer<t>, Function<t, r>, respectively.
predicate:
@FunctionalInterface Public
interface predicate<t> {
/**
* evaluates this predicate on the given argument.
*
@param t the input argument
* @return {@code true} if the input argument matches the predicate,
* Otherwis e {@code false}
*
/Boolean test (t);
}
The predicate function is similar to the above applefilter, using the conditions we set externally to validate the incoming parameters and return a Boolean of the validation results, using predicate to filter the elements of the list collection:
/**
*
@param list
* @param predicate *
@param <T>
* @return
/Public <t > list<t> Filter (list<t> List, predicate<t> predicate) {
list<t> newlist = new ArrayList <T> ();
For (final T t:list) {
if (predicate.test (t)) {
newlist.add (t);
}
}
return newlist;
}
Use:
Demo.filter (list, (String str)-> null!= str &&!str.isempty ());
Consumer
@FunctionalInterface Public
interface consumer<t> {
/**
* Performs this operation on the given argument.
*
@param t the input argument *
/Void accept (T);
}
Consumer provides a accept abstract function that receives parameters but does not return a value, using consumer to traverse the collection.
/**
* Traversing the collection, performing custom Actions
* *
@param list
* @param consumer
* @param <T>
/Public <T> void Filter (list<t> List, consumer<t> Consumer) {for
(final T t:list) {
consumer.accept (t);
}
Using the above functional interface, iterate through the collection of strings and print a non-empty string:
Demo.filter (list, (String str)-> {
if (Stringutils.isnotblank (str)) {
System.out.println (str);
}
});
Function
@FunctionalInterface public
Interface Function<t, r> {
/**
* applies this Function to the given Argumen T.
*
@param t the function argument
* @return The function result *
/R apply (t);
}
Funcation performs the conversion operation, entering data of type T, returning data of type R, and using function to convert the collection:
Public <t, r> list<r> filter (list<t> List, function<t, r> Function) {
list<r> newlist = new arraylist<r> ();
For (final T t:list) {
newlist.add (function.apply (t));
}
return newlist;
}
Other:
Demo.filter (list, (String str)-> integer.parseint (str));
The above functional interfaces also provide a default implementation of some logical operations, and leave it to the default method that describes the Java8 interface later.
Some things to be aware of during use:
Type inference:
In the coding process, sometimes it may be doubtful that our calling code will specifically match which functional interface, in fact the compiler will make the correct decision based on the parameters, return type, exception type (if any).
You can further simplify the code by omitting the type of the argument at some point when the call is specific:
Filter Apple
list<apple> filterapples = Filterapplesbyapplefilter (apples, apple apple
)-> Color.RED.equals (Apple.getcolor ()) && apple.getweight () >=);
In some cases we can even omit the parameter type, and the compiler will correctly judge
the list<apple> filterapples = Filterapplesbyapplefilter (apples) according to the context.
Apple-> COLOR.R
ed.equals (Apple.getcolor ()) && apple.getweight () >= 100);
Local variables
For all of the above examples, our lambda expressions use their principal arguments, and we can also use local variables in the lambda, as follows
int weight = m;
list<apple> filterapples = Filterapplesbyapplefilter (apples,
Apple-> Color.RED.equals (apple.getcolor ()) && apple.getweight () >= weight);:
In this example we use a local variable weight in a lambda, but using a local variable in a lambda must require that the variable be explicitly declared final or de facto final, mainly because the local variable is stored on the stack, and the lambda expression runs in another thread, When the thread view accesses the local variable, the variable has the possibility of being changed or recycled, so there is no thread-safe problem with final adornments.
Four. Method reference
Using a method reference can be a step closer to simplifying the code, and sometimes this simplification makes the code look more intuitive, first look at an example:
/* ... Omit apples initialization/
/////Use lambda expression
apples.sort (Apple A, Apple B)-> Float.compare (A.getweight (), B.getweight ()));
The method is used to refer to
apples.sort (comparator.comparing (apple::getweight));
Method Reference by:: The method of membership and the method itself connected, mainly divided into three categories:
static method
(args)-> Classname.staticmethod (args)
Converted Into
instance method of a parameter
(args)-> Args.instancemethod ()
Converted Into
Classname::instancemethod//ClassName is the type of args
An external instance method
(args)-> Ext.instancemethod (args)
Converted Into
Ext::instancemethod (args)
Reference:
Http://www.codeceo.com/article/lambda-of-java-8.html
The above is a small set to introduce the new characteristics of the JDK8 lambda expression, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!