JDK8 new Features: Use method references implementation methods reuse, simplify lambda expression __ method reference

Source: Internet
Author: User
Tags instance method pow

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


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.