Lambd表達(dá)式的使用
范例:傳統(tǒng)的面向?qū)ο箝_(kāi)發(fā)
interface IMessage2{
void print();
}
public class TestDemo {
public static void main(String[] args) {
IMessage2 message2 = new IMessage2() {//匿名內(nèi)部類
@Override
public void print() {
System.out.println("MyMessage");
}
};
message2.print();
}
}
對(duì)于此類操作有了更簡(jiǎn)化實(shí)現(xiàn),如果采用函數(shù)式編程,則代碼如下:
范例:函數(shù)式編程
@FunctionalInterface//表明函數(shù)式編程
interface IMymessage3{
void print();
}
public class Test16 {
public static void main(String[] args) {
IMymessage3 mymessage3 =()-> System.out.println("MyMessage");
mymessage3.print();
}
}
面向?qū)ο笳Z(yǔ)法最大的局限:結(jié)構(gòu)必須非常完整。
要想使用函數(shù)式編程有一個(gè)前提:接口必須只有一個(gè)抽象方法,如果有兩個(gè)抽象方法,則無(wú)法使用函數(shù)式編程。如果現(xiàn)在某個(gè)接口就是為了函數(shù)式編程而生的,最好定義時(shí)就讓其只能夠定義一個(gè)抽象方法,所以有了一個(gè)新注解@FunctionalInterface注解。
Lambda表達(dá)式語(yǔ)法
Lambda表達(dá)式語(yǔ)法:(參數(shù)) -> {} ;(多行時(shí)),(參數(shù)) -> 單行語(yǔ)句.
范例:多行語(yǔ)句
@FunctionalInterface
interface IMessage{
public void print();
}
public class TestDemo{
public static void main(String[] args){
IMessage message = () -> {
System.out.println("hello");
System.out.println("world");
System.out.println("hello world");
};
message.print();
}
}
如果現(xiàn)在你的表達(dá)式里只有一行進(jìn)行數(shù)據(jù)的返回,那么直接使用語(yǔ)句即可,可以不使用return
范例:直接進(jìn)行計(jì)算
@FunctionalInterface
interface IMath{
int add(int a,int b);
}
public class Test17 {
public static void main(String[] args) {
IMath math = (p1,p2) ->(p1+p2);
System.out.println(math.add(20,30));
}
}
方法引用
引用靜態(tài)方法:類名稱::static 方法名
引用某個(gè)對(duì)象的方法:實(shí)例化對(duì)象::方法名
引用某個(gè)特定類的方法:類名稱::普通方法
引用構(gòu)造方法:類名稱::new
范例:String類的valueOf()方法
/**
* 靜態(tài)方法的引用
* @author 喵先生
*
* @param <P>
* @param <R>
*/
@FunctionalInterface
interface IMyMessage<P, R> {
R switchPara(P p);
}
public class Test1 {
public static void main(String[] args) {
IMyMessage<Integer, String> message = String::valueOf;// 進(jìn)行方法引用
String str = message.switchPara(100);// 相當(dāng)于調(diào)用了String.valueOf
System.out.println(str.length());
}
}
范例:引用對(duì)象方法
String中的toUpperCase()方法為對(duì)象方法
/**
* 引用對(duì)象方法:String中的toUpperCase()方法為對(duì)象方法
* @author 喵先生
*
* @param <R>
*/
@FunctionalInterface
interface IMyMessage2<R> {
R switchpara();
}
public class Test2 {
public static void main(String[] args) {
IMyMessage2<String> iMyMessage5 = "hello"::toUpperCase;
System.out.println(iMyMessage5.switchpara());
}
}
范例:引用類中普通方法
String類中有一個(gè)compareTo方法,此方法為普通方法
/**
* 引用類中普通方法:String類中有一個(gè)compareTo方法,此方法為普通方法
* @author 喵先生
*
* @param <R>
* @param <P>
*/
@FunctionalInterface
interface IMyMessage6<R, P> {
R compare(P p1, P p2);
}
public class Test3 {
public static void main(String[] args) {
IMyMessage6<Integer, String> message6 = String::compareTo;
System.out.println(message6.compare("侯", "姚"));
}
}
范例:引用構(gòu)造方法
public class Student {
String name;
int age;
String area;
public Student() {}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/**
* 引用構(gòu)造方法
*
* @author 喵先生
*
* @param <R>
* @param <PN>
* @param <PA>
*/
@FunctionalInterface
interface IMyPerson<R,PN,PA>{
R message(PN name,PA age);
}
public class Test4 {
public static void main(String[] args) {
IMyPerson<Student,String,Integer> myPerson = Student::new;
System.out.println(myPerson.message("Jack",21));
}
}
內(nèi)建函數(shù)式接口
Lambda的核心在于:函數(shù)式接口。而函數(shù)式接口的核心:只有一個(gè)抽象方法
java.util.function實(shí)際上函數(shù)式編程分為以下四種接口:
功能性函數(shù)式接口:public interface Function<R,T> R apply(T t);
供給型函數(shù)式接口: public interface Supplier T get();
消費(fèi)型函數(shù)式接口:public interface Consumer void accept(T t);
斷言型接口:public interface Predicate boolean test(T t);
功能型接口
功能型指的是你輸入一個(gè)數(shù)據(jù),而后將數(shù)據(jù)處理后進(jìn)行輸出
實(shí)際上所有的函數(shù)式接口里面都會(huì)有一些小的擴(kuò)展。
import java.util.function.Function;
/**
* 功能型指的是你輸入一個(gè)數(shù)據(jù),而后將數(shù)據(jù)處理后進(jìn)行輸出
* 實(shí)際上所有的函數(shù)式接口里面都會(huì)有一些小的擴(kuò)展
*
* @author 喵先生
*
*/
public class Test1 {
public static void main(String[] args) {
Function<Integer, String> function = String::valueOf;
String str = function.apply(100);
System.out.println(str.length());
}
}
如果現(xiàn)在確定操作的數(shù)據(jù)是int,則可以使用IntFunction接口
import java.util.function.IntFunction;
/**
* 如果現(xiàn)在確定操作的數(shù)據(jù)是int,則可以使用IntFunction接口
* @author 喵先生
*
*/
public class Test2 {
public static void main(String[] args) {
// 注意這里的接口名和之前不同
IntFunction<String> function = String::valueOf;
String str = function.apply(111);
System.out.println(str.length());
}
}
供給型接口
import java.util.function.Supplier;
/**
* 供給型接口
* @author 喵先生
*
*/
public class Test3 {
public static void main(String[] args) {
Supplier<String> stringSupplier = "hello"::toUpperCase;
System.out.println( stringSupplier.get() );
}
}
消費(fèi)型接口
import java.util.function.Consumer;
/**
* 消費(fèi)型接口
* @author 喵先生
*
*/
public class Test4 {
public static void main(String[] args) {
Consumer<String> consumer = System.out::println;
consumer.accept("hehe");
}
}
斷言型接口
import java.util.function.Predicate;
/**
* 斷言型接口
* @author 喵先生
*
*/
public class Test5 {
public static void main(String[] args) {
Predicate<String> pre = "###123shdsb"::startsWith;
System.out.println( pre.test("##") );
}
}