The previous article has introduced the function interface and the lambda expression, this article mainly studies the method reference. Using method references, you can reduce the writing of lambda expressions, which is commonly used in the stream APIs.
A section of code contrasts the lambda with the static method reference:
list<integer> ids = arrays.aslist (1, 2, 5, 4, 3);
Use lambda expression
comparator<integer> Comparator1 = (A, b)-> a-b;
Use static method to reference
comparator<integer> Comparator2 = integer::compare;
list<integer> sorted1 = Ids.stream (). Sorted (Comparator1). Collect (Collectors.tolist ());
list<integer> sorted2 = Ids.stream (). Sorted (Comparator2). Collect (Collectors.tolist ());
System.out.println (IDs);//[1, 2, 5, 4, 3]
System.out.println (sorted1);//[1, 2, 3, 4, 5]
System.out.println (sor TED2); [1, 2, 3, 4, 5]
We want to sort the integer list, use the lambda we have to write ourselves a comparator object (although it is also very simple), in fact, the JDK class library has provided a similar implementation, we can refer to the existing methods through Integer::compare.
The method references in JDK8 are divided into 4 classes: Static method references, instance method references, construction method references, and statically referencing instance methods.
(1). static method Reference
Format: Classname::staticmethodname, for example:
String::valueof equivalent to lambda expression (s)-> string.valueof (s)
Math::p ow is equivalent to a lambda expression (x, y)-> Math.pow (x, y-axis)
@FunctionalInterface Public
interface MyInterface {public
double calculate (double A, double b);
}
static method References Pow
myinterface ins1 = Math::p ow;
System.out.println (Ins1.calculate (2, 4) = =);
static method references Max
myinterface ins2 = Math::max;
System.out.println (Ins2.calculate (2, 4) = = 4);
You can see the functional interface MyInterface that we define, we have to refer to the static method, have the same return value and the join parameter.
(2). Instance method Reference
Format: Instancereference::methodname, for example:
Str::tostring equivalent to lambda expression ()-> str.tostring ()
Str::concat equivalent to lambda expression (another)-> Str.concat (another)
@FunctionalInterface Public
interface MyInterface {
//String.Concat () the same argument and return value public
String transform (String input);
}
String content = "abc";
instance method referencing String class
myinterface ins1 = content::concat;
System.out.println (Ins1.transform ("Def"));//ABCdef
You can see the effect we've achieved: Define a functional interface that has the same parameter type and return value as the original concat, which is equivalent to renaming the concat.
(3). Construct Method Reference
Format: classname::new, if the ClassName has more than one constructor, the JDK automatically determines where to use a constructor based on the method declaration of the functional interface.
public class Target {public
int attr = 0;
Public target () {
} is public
target (int b) {
this.attr = b;
}
}
@FunctionalInterface Public
interface MyInterface {public
Target create (int value);
}
MyInterface ins = target::new;
Target t = ins.create (1); You can automatically infer the constructor used
System.out.println (t.attr);//1
The constructor of an array is similar, but the constructor has a parameter (the length of the array).
@FunctionalInterface Public
interface MyInterface {public
int[] Create (int length);
}
MyInterface ins = int[]::new;
int[] Array = ins.create (a);
System.out.println (array.length);//10
(4). Referencing an instance method in a static way
I don't know what the name is, let's call it that. static method references and instance method references on types have the same syntax, and the compiler makes decisions based on the actual situation.
Format: Classname::instancemethod, for example:
String::tostring equivalent to lambda expression (String s)-> s.tostring ()
the first parameter of the lambda becomes the object that invokes the instance method .
public class Target {
private int attr = 0;
Public Target (int attr) {
this.attr = attr;
}
public int CompareTo (Target another) {return
this.attr-another.attr;
}
public static int Compare (target one, target another) {return
one.attr-another.attr;
}
}
Functional interface: Implementing target object comparison
@FunctionalInterface public
interface MyInterface {public
int compare (target One, Target another);
}
Target Target1 = new Target (a);
Target Target2 = new target (MB);
Reference instance method
MyInterface ins1 = target::compare;
System.out.println (Ins1.compare (Target1, Target2));// -90
//reference static method
MyInterface ins2 = target::compare;
System.out.println (Ins2.compare (Target1, Target2));//90
Finally, let's look at the power of the method reference:
public class Person {
private String name;
Private Date birthday;
Public person (String name, Date birthday) {
this.name = name;
This.birthday = birthday;
}
Public Date Getbirthday () {return
birthday;
}
public void Setbirthday (Date birthday) {
this.birthday = birthday;
}
@Override public
String toString () {return
"person{" +
"name= '" + name + ' \ ' +
", birthday=" + Birth Day +
'} ';
}
list<person> persons = new arraylist<> ();
Persons.add (New person ("C", "2017-01-01"));
Persons.add (New person ("B", "2016-01-01"));
Persons.add (New Person ("A", "2015-01-01"));
Now we want to sort the persons collection by name:
Mode 1
collections.sort (persons, new comparator<person> () {
@Override public
int compare (person O1, Person O2) {return
o1.getname (). CompareTo (O2.getname ());
}
);
SYSTEM.OUT.PRINTLN (persons);
One way is to compare the traditional practice of implementing a comparator comparator.
Mode 2
collections.sort (persons, (O1, O2)->o1.getname (). CompareTo (O2.getname ()));
SYSTEM.OUT.PRINTLN (persons);
Mode 2 uses a lambda expression
Mode 3
collections.sort (persons, Comparator.comparing (Person::getname));
SYSTEM.OUT.PRINTLN (persons);
Mode 3 uses the method reference to reuse the comparison logic without realizing the comparator itself.
Reference article: https://my.oschina.net/luoyezhuifeng/blog/801343