目录
2、消费型函数式接口(与上面的区别是只进行数据的处理,没有任何返回)
1、引入Lambda表达式
java从JDK1.8开始为了简化使用者进行代码的开发,专门提供有Lambda表达式的支持。利用函数式编程可以避免掉面向对象编程中的一些繁琐的处理问题。
- 如下匿名内部类:核心代码就第8行,整体显得太繁琐了。
public class JavaDemo {
public static void main(String[] args) {
Imessage msg = new Imessage() {
public void send(String str) {
System.out.println("消息发送:" + str);
}
};
msg.send("www.loong.cn");
}
}
- 使用Lambda表达式改造
public class JavaDemo {
public static void main(String[] args) {
Imessage msg = (str) -> {
System.out.println("消息发送:" + str);
};
msg.send("www.loong.cn");
}
}
现在整个代码里面就写了一行语句,这种形式避免了复杂的面向对象结构化要求。
Lambda表达式如果想用,要求是SAM(Single Abstract Method),只有一个抽象方法,以之前的IMessage接口为例,在这个接口里面发现只是提供一个send()方法,除此之外没有任何的其他方法定义,所以这样的接口就被称为函数式接口,只有函数式接口才能被Lamda表达式使用。
- 函数式接口注解
接口上使用了@FunctionalInterface后,必须只有一个抽象方法,不然编译会报错
@FunctionalInterface
public interface Imessage{
public void send(String str);
}
对于Lambda表达式而言,提供有如以下几种格式:
- 方法没有参数:()->{};
- 方法有参数:(参数,参数)->{};
- 如果现在只有一行语句返回:(参数,参数)->语句;
@FunctionalInterface
interface IMath {
public int add(int x, int y);
}
public class JavaDemo {
public static void main(String[] args) {
IMath iMath = (t1, t2) -> {
return t1 + t2;
};
System.out.println(iMath.add(2, 5));
}
}
2、方法引用
引用数据类型最大的特点是可以进行内存的指向处理,但是再传统的开发之中一直所使用的只是对象引用操作,之后也提供有方法的引用,即:不同的方法名称可以描述同一个方法。
- 引用静态方法:类名::static方法名称;
@FunctionalInterface
interface IFunction<P,R> {
public R change(P p);
}
利用方法引用这个概念可以为一个方法定义多个名字,但是必须要求函数式接口。
public class JavaDemo {
public static void main(String[] args) {
IFunction<Integer, String> fun = String::valueOf;
String str = fun.change(100);
System.out.println(str.length());
}
}
- 引用某个实例对象的方法:实例化对象::普通方法;
@FunctionalInterface
interface IFunction<R> {
public R upper();
}
public class JavaDemo {
public static void main(String[] args) {
String ss = "hello world";
IFunction<String> fun = ss::toUpperCase;
System.out.println(fun.upper());
}
}
- 引用特定类型的方法:特定类::普通方法;
@FunctionalInterface
interface IFunction<P> {
public int compare(P p1, P p2);
}
public class JavaDemo {
public static void main(String[] args) {
IFunction<String> fun = String::compareTo;
System.out.println(fun.compare("A", "a"));
}
}
- 引用构造方法:类名称::new。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public String toString(){
return "姓名:" + this.name+"、年龄:"+this.age;
}
}
@FunctionalInterface
interface IFunction<R> {
public R create(String s, int a);
}
public class JavaDemo {
public static void main(String[] args) {
IFunction<Person> fun = Person::new;
System.out.println(fun.create("张三", 20));
}
}
3、内建函数式接口
在系统中专门提供有一个java.util.function的开发包,里面可以直接使用函数式接口供使用:
1、功能型函数式接口:
比如:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
import java.util.function.*;
public class JavaDemo {
public static void main(String[] args) {
Function<String, Boolean> fun = "**Hello"::startsWith;
System.out.println(fun.apply("**"));
}
}
2、消费型函数式接口(与上面的区别是只进行数据的处理,没有任何返回)
例如:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
import java.util.function.*;
public class JavaDemo {
public static void main(String[] args) {
Consumer<String> fun = System.out::println;
fun.accept("hello");
}
}
3、供给型函数式接口(没有接收参数,只有返回值)
@FunctionalInterface
public interface Supplier<T> {
T get();
}
public class JavaDemo {
public static void main(String[] args) {
Supplier<String> fun = "hello"::toUpperCase;
System.out.println(fun.get());
}
}
4、断言型函数式接口(进行判断处理)
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
import java.util.function.*;
public class JavaDemo {
public static void main(String[] args) {
Predicate<String> fun = "hello"::equalsIgnoreCase;
System.out.println(fun.test("HELLO"));
}
}