1 函数式接口
(1)函数式接口就是有且仅有一个抽象方法并且可以有多个非抽象方法的接口。
(2)注解@FunctionalInterface可以检查一个接口是不是函数式接口。
(3)在函数式接口中,可以定义默认方法。
(4)在函数式接口中,可以定义静态方法。
(5)在函数式接口中,可以定义Object类中的public方法,函数式接口不把这些方法当作抽象方法(虽然这些方法是抽象方法)。
@FunctionalInterface
public interface GreetingService {
void sayMessage(String message);
default void doSomeMoreWork() {
// Method body
}
static void printHello() {
System.out.println("Hello");
}
public boolean equals(Object obj);
}
2 Java中的部分函数式接口
(1)Runnable接口
(2)Callable<V>接口
(3)Comparator<T>接口
(4)Supplier<T>接口:代表一个输出。
(5)Consumer<T>接口:代表一个输入。
(6)BiConsumer<T, U>接口:代表两个输入。
(7)Function<T, R>接口:代表一个输入,一个输出。
(8)UnaryOperator<T>接口:继承了Function<T, T>接口,代表一个输入,一个输出,输入和输出类型相同。
(9)BiFunction<T, U, R>接口:代表两个输入,一个输出。
(10)BinaryOperator<T>:继承了BiFunction<T,T,T>接口,代表两个输入,一个输出,输入和输出类型相同。
3 Lambda表达式
Lambda表达式是一个对象,是函数式接口的一个实例。
4 Lambda表达式语法
(函数式接口中的抽象方法的参数) -> {函数式接口中的抽象方法的实现}
(1)函数式接口中的抽象方法只有一个参数时,()可以省略。
(2)函数式接口中的抽象方法的实现只有一条语句时,{}可以省略。
(3)函数式接口中的抽象方法有返回值并且抽象方法的实现只有一条return语句时,{}和return可以省略。
5 Lambda表达式示例
(1)无参数+无返回值:() -> { System.out.println(1); }
(2)无参数+无返回值:() -> System.out.println(1)
(3)无参数+有返回值:() -> { return 100; }
(4)无参数+有返回值:() -> 100
(5)有参数+有返回值:(x) -> { return x+1; }
(6)有参数+有返回值:x -> x+1
public class LambdaTest {
public static void main(String[] args) {
Runnable r1 = () -> {
System.out.println(100);
};
r1.run();
Runnable r2 = () -> {
System.out.println(100);
};
r2.run();
Callable<String> c1 = () -> {
return "hello";
};
Callable<String> c2 = () -> "hello";
try {
System.out.println(c1.call());
System.out.println(c2.call());
} catch (Exception e) {
e.printStackTrace();
}
Function<Integer, Integer> f1 = a -> {
int sum = 0;
for (int i = 0; i <= a; i++) {
sum += i;
}
return sum;
};
System.out.println(f1.apply(10));
BiFunction<String, String, Integer> bf = (a, b) -> a.length() + b.length();
System.out.println(bf.apply("nba", "cba"));
}
}
6 方法的引用
6.1 静态方法的引用
(1)Lambda表达式:(args) -> 类名.静态方法(args)
(2)静态方法的引用:类名::静态方法
public class Example1 {
public static String take() {
return "hello";
}
public static void put(Integer size) {
System.out.println("size : " + size);
}
public static String toUpperCase(String str) {
return str.toUpperCase();
}
public static Integer getLength(String s1, String s2) {
return s1.length() + s2.length();
}
public static void main(String[] args) {
Supplier<String> s1 = () -> Example1.take();
Supplier<String> s2 = Example1::take;
System.out.println(s1.get());// 输出hello
System.out.println(s2.get());// 输出hello
Consumer<Integer> c1 = (size) -> Example1.put(size);
Consumer<Integer> c2 = Example1::put;
c1.accept(100);// 输出size : 100
c2.accept(200);// 输出size : 200
Function<String, String> f1 = str -> str.toUpperCase();
Function<String, String> f2 = str -> Example1.toUpperCase(str);
Function<String, String> f3 = Example1::toUpperCase;
System.out.println(f1.apply("lambda"));
System.out.println(f2.apply("lambda"));
System.out.println(f3.apply("lambda"));
BiFunction<String, String, Integer> bf1 = (ss1, ss2) -> ss1.length() + ss2.length();
BiFunction<String, String, Integer> bf2 = (ss1, ss2) -> Example1.getLength(ss1, ss2);
BiFunction<String, String, Integer> bf3 = Example1::getLength;
System.out.println(bf1.apply("java", "se"));// 输出6
System.out.println(bf2.apply("java", "ee"));// 输出6
System.out.println(bf3.apply("java", "me"));// 输出6
}
}
6.2 实例对象方法的引用
(1)Lambda表达式:(args) -> instance.instanceMethod(args)
(2)实例对象方法的引用:instance::instanceMethod
public class Base {
public String toUpper(String str) {
System.out.println("Base to upper");
return str.toUpperCase();
}
}
public class Example2 extends Base {
public String take() {
return "hello";
}
public void put(Integer size) {
System.out.println("size : " + size);
}
public String toUpper(String str) {
System.out.println("Example2 to upper");
return str.toUpperCase();
}
public Integer getLength(String s1, String s2) {
return s1.length() + s2.length();
}
public void test() {
Function<String, String> f1 = this::toUpper;
System.out.println(f1.apply("lambda"));
Function<String, String> f2 = super::toUpper;
System.out.println(f2.apply("lambda"));
}
public static void main(String[] args) {
Supplier<String> s1 = () -> new Example2().take();
Supplier<String> s2 = new Example2()::take;
System.out.println(s1.get());// 输出hello
System.out.println(s2.get());// 输出hello
Consumer<Integer> c1 = (size) -> new Example2().put(size);
Consumer<Integer> c2 = new Example2()::put;
c1.accept(100);// 输出size : 100
c2.accept(200);// 输出size : 200
Function<String, String> f1 = str -> str.toUpperCase();
Function<String, String> f2 = str -> new Example2().toUpper(str);
Function<String, String> f3 = new Example2()::toUpper;
System.out.println(f1.apply("lambda"));
System.out.println(f2.apply("lambda"));
System.out.println(f3.apply("lambda"));
BiFunction<String, String, Integer> bf1 = (ss1, ss2) -> ss1.length() + ss2.length();
BiFunction<String, String, Integer> bf2 = (ss1, ss2) -> new Example2().getLength(ss1, ss2);
BiFunction<String, String, Integer> bf3 = new Example2()::getLength;
System.out.println(bf1.apply("java", "se"));// 输出6
System.out.println(bf2.apply("java", "ee"));// 输出6
System.out.println(bf3.apply("java", "me"));// 输出6
Example2 example2 = new Example2();
example2.test();
}
}
6.3 构造方法的引用
(1)Lambda表达式:(args) -> new 类名(args)
(2)实例对象方法的引用:类名::new
public class Example3 {
public static void main(String[] args) {
Supplier<String> s1 = () -> new String();
Supplier<String> s2 = String::new;
System.out.println(s1.get());
System.out.println(s2.get());
Consumer<Integer> c1 = (num) -> new Account(num);
Consumer<Integer> c2 = Account::new;
c1.accept(100);
c2.accept(200);
Function<String, Account> f1 = (str) -> new Account(str);
Function<String, Account> f2 = Account::new;
f1.apply("lambda");
f2.apply("java");
}
}
class Account {
public Account(int age) {
System.out.println("Account(age) : " + age);
}
public Account(String name) {
System.out.println("Account(name) : " + name);
}
}
6.4 特定对象方法的引用
(1)Lambda表达式:(instance类型的参数,args) -> instance.instanceMethod(args)
(2)实例对象方法的引用:类名::instanceMethod
public class Example4 {
public void not() {
Runnable run = () -> {
};
Closeable c = () -> {
};
Supplier<String> s = () -> "";
}
public static void main(String[] args) {
Consumer<Too> c1 = (too) -> new Too().foo();
Consumer<Too> c2 = Too::foo;
c1.accept(new Too());
c2.accept(new Too());
BiConsumer<Too2, String> b1 = (too2, str) -> new Too2().foo(str);
BiConsumer<Too2, String> b2 = Too2::foo;
b1.accept(new Too2(), "java");
b2.accept(new Too2(), "lambda");
BiFunction<Prod, String, Integer> bf1 = (p, s) -> new Prod().fun(s);
BiFunction<Prod, String, Integer> bf2 = Prod::fun;
System.out.println(bf1.apply(new Prod(), "java"));
System.out.println(bf2.apply(new Prod(), "lambda"));
}
}
class Too {
public void foo() {
System.out.println("foo");
}
}
class Too2 {
public void foo(String str) {
System.out.println("foo : " + str);
}
}
class Prod {
public Integer fun(String str) {
if (str == "java")
return 1;
else if (str == "lambda")
return -1;
else
return 0;
}
}
网友评论