1、函数式接口
函数式接口主要指只包含一个抽象方法的接口,Java8提供@FunctionalInterface注解来定义函数式接口,若定义的接口不符合函数式的规范便会报错,并且增加了java.util.function包,该包包含了常用的函数式接口。
2、匿名内部类和Lambda表达式实现函数式接口
lambda表达式:参数列表、箭头符号->和方法体组成,而方法体中可以是表达式,也可以是语句块。
语法格式:(参数列表) -> { 方法体; } - 其中()、参数类型、{} 以及return关键字 可以省略
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class FunctionalInterfaceTest {
public static void main(String[] args) {
// 1.匿名内部类的语法格式: 父类/接口类型 引用变量名 = new 父类/接口类型(){ 方法的重写 };
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("我是既没有参数又没有返回值的方法!");
}
};
runnable.run(); // 我是既没有参数又没有返回值的方法!
// 使用lambda表达式实现函数式接口对象的创建: (参数列表)->{方法体;}
//Runnable runnable1 = () -> { System.out.println("我是既没有参数又没有返回值的方法!"); };
Runnable runnable1 = () -> System.out.println("我是既没有参数又没有返回值的方法!");
runnable1.run();
System.out.println("----------------------------------------------------------------------");
Consumer consumer = new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o + "有参但没有返回值的方法就是我!");
}
};
consumer.accept("友情提示:"); // 友情提示:有参但没有返回值的方法就是我!
//Consumer consumer1 = (Object o) -> {System.out.println(o + "有参但没有返回值的方法就是我!");};
//Consumer consumer1 = (o) -> System.out.println(o + "有参但没有返回值的方法就是我!");
// 省略了()、参数类型、{}, 自动类型推断
Consumer consumer1 = o -> System.out.println(o + "有参但没有返回值的方法就是我!");
consumer1.accept("友情提示:");
System.out.println("----------------------------------------------------------------------");
Supplier supplier = new Supplier() {
@Override
public Object get() {
return "无参有返回值!";
}
};
System.out.println(supplier.get()); // 无参有返回值
//Supplier supplier1 = () -> {return "无参有返回值!";};
Supplier supplier1 = () -> "无参有返回值!";
System.out.println(supplier1.get());
System.out.println("----------------------------------------------------------------------");
Function function = new Function() {
@Override
public Object apply(Object o) {
return o;
}
};
System.out.println(function.apply("有参有返回值的方法")); // 有参有返回值的方法
// return 和 {} 都可以省略
Function function1 = o -> o;
System.out.println(function1.apply("有参有返回值的方法"));
System.out.println("----------------------------------------------------------------------");
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
System.out.println(comparator.compare(10, 20)); // 0
Comparator comparator1 = (o1, o2) -> 0;
System.out.println(comparator1.compare(10, 20));
System.out.println("----------------------------------------------------------------------");
Predicate predicate = new Predicate() {
@Override
public boolean test(Object o) {
return false;
}
};
System.out.println(predicate.test("hello")); // false
Predicate predicate1 = o -> false;
System.out.println(predicate1.test("hello"));
}
}
3、方法引用实现函数式接口
person类:
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("没事出来秀一下哦");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
//return getName().compareTo(o.getName());
return getAge() - o.getAge();
}
}
测试类:
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class MethodReferenceTest {
public static void main(String[] args) {
// 1.使用匿名内部类的方式通过函数式接口Runnable中的方法实现对Person类中show方法的调用
Person person = new Person("zhangfei", 30);
Runnable runnable = new Runnable() {
@Override
public void run() {
person.show();
}
};
runnable.run(); // 没事出来秀一下哦
System.out.println("-------------------------------------------------------------");
// 2.使用lambda表达式的方式实现Person类中show方法的调用
Runnable runnable1 = () -> person.show();
runnable1.run(); // 没事出来秀一下哦
System.out.println("-------------------------------------------------------------");
// 3.使用方法引用的方式实现Person类中show方法的调用
Runnable runnable2 = person::show;
runnable2.run();
System.out.println("-------------------------------------------------------------");
// 4.使用匿名内部类的方式通过函数式接口Consumer中的方法来实现Person类中setName方法的调用
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
person.setName(s);
}
};
consumer.accept("guanyu");
System.out.println("person = " + person); // guanyu 30
System.out.println("-------------------------------------------------------------");
// 5.使用lambda表达式的方式实现Person类中setName方法的调用
Consumer<String> consumer1 = s -> person.setName(s);
consumer1.accept("liubei");
System.out.println("person = " + person); // liubei 30
System.out.println("-------------------------------------------------------------");
// 6.使用方法引用的方式实现Person类中setName方法的调用
Consumer<String> consumer2 = person::setName;
consumer2.accept("zhangfei");
System.out.println("person = " + person); // zhangfei 30
System.out.println("-------------------------------------------------------------");
// 7.使用匿名内部类的方式通过函数式接口Supplier中的方法来实现Person类中getName方法的调用
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return person.getName();
}
};
System.out.println(supplier.get()); // zhangfei
Supplier<String> supplier1 = () -> person.getName();
System.out.println(supplier1.get()); // zhangfei
Supplier<String> supplier2 = person::getName;
System.out.println(supplier2.get()); // zhangfei
System.out.println("-------------------------------------------------------------");
// 8.使用匿名内部类的方式通过函数式接口Function中的方法实现Integer类中parseInt方法的调用
Function<String, Integer> function = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
};
System.out.println(function.apply("12345")); // 12345
Function<String, Integer> function1 = s -> Integer.parseInt(s);
System.out.println(function1.apply("12345")); // 12345
Function<String, Integer> function2 = Integer::parseInt;
System.out.println(function2.apply("12345")); // 12345
System.out.println("-------------------------------------------------------------");
// 9.使用匿名内部类的方式通过函数式接口Comparator中的方法实现Integer类中compare方法的调用
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
System.out.println(comparator.compare(10, 20)); // -1
Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1, o2);
System.out.println(comparator1.compare(10, 20)); // -1
Comparator<Integer> comparator2 = Integer::compare;
System.out.println(comparator2.compare(10, 20)); // -1
System.out.println("-------------------------------------------------------------");
// 10.使用匿名内部类的方式通过类名来调用非静态方法
// 其中一个参数对象作为调用对象来调用方法时,可以使用上述方式 更抽象
Comparator<Integer> comparator3 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
System.out.println(comparator3.compare(10, 20)); // -1
Comparator<Integer> comparator4 = (o1, o2) -> o1.compareTo(o2);
System.out.println(comparator4.compare(10, 20)); // -1
Comparator<Integer> comparator5 = Integer::compareTo;
System.out.println(comparator5.compare(10, 20)); // -1
System.out.println("-------------------------------------------------------------");
// 11.使用匿名内部类的方式通过Supplier函数式接口创建Person类型的对象并返回
Supplier<Person> supplier3 = new Supplier<Person>() {
@Override
public Person get() {
return new Person();
}
};
System.out.println(supplier3.get()); // null 0
Supplier<Person> supplier4 = () -> new Person();
System.out.println(supplier4.get()); // null 0
Supplier<Person> supplier5 = Person::new;
System.out.println(supplier5.get()); // null 0
System.out.println("-------------------------------------------------------------");
// 12.使用匿名内部类的方式通过BiFunction函数式接口采用有参方式创建Person类型的对象并返回
BiFunction<String, Integer, Person> biFunction = new BiFunction<String, Integer, Person>() {
@Override
public Person apply(String s, Integer integer) {
return new Person(s, integer);
}
};
System.out.println(biFunction.apply("zhangfei", 30)); // zhangfei 30
BiFunction<String, Integer, Person> biFunction1 = (s, integer) -> new Person(s, integer);
System.out.println(biFunction1.apply("zhangfei", 30)); // zhangfei 30
BiFunction<String, Integer, Person> biFunction2 = Person::new;
System.out.println(biFunction2.apply("zhangfei", 30)); // zhangfei 30
System.out.println("-------------------------------------------------------------");
// 12.使用匿名内部类的方式通过Function函数式接口创建指定数量的Person类型的对象数组并返回
Function<Integer, Person[]> function3 = new Function<Integer, Person[]>() {
@Override
public Person[] apply(Integer integer) {
return new Person[integer];
}
};
Person[] pArr = function3.apply(3);
System.out.println(Arrays.toString(pArr));
Function<Integer, Person[]> function4 = integer -> new Person[integer];
System.out.println(Arrays.toString(function4.apply(4)));
Function<Integer, Person[]> function5 = Person[]::new;
System.out.println(Arrays.toString(function5.apply(5)));
}
}
4、Stream接口
5、Optional类