目录
一、匿名内部类
匿名内部类也就是没有名字的内部类
正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
1、在抽象类上使用匿名内部类
public class Test {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
void eat() {
System.out.println("eat");
}
@Override
void cry() {
System.out.println("cry");
}
};
animal.eat();
animal.cry();
animal.show();
}
}
abstract class Animal {
abstract void eat();
abstract void cry();
void show() {
System.out.println("show");
}
}
运行结果:
eat
cry
show
2、在接口上使用匿名内部类
public class Test {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
public void eat() {
System.out.println("abstract===eat");
}
@Override
public void cry() {
System.out.println("abstract===cry");
}
};
animal.eat();
animal.cry();
Animal.show();
Animal.show1();
animal.show2();
}
}
interface Animal {
void eat();
void cry();
static void show() {
System.out.println("static===show===接口的static方法只能使用接口名.方法名来调用,且可以有多个static方法");
}
static void show1() {
System.out.println("static===show1");
}
default void show2() {
System.out.println("default===show2===接口有且只能有一个default方法");
}
}
运行结果:
abstract===eat
abstract===cry
default===show2
接口的static方法只能使用接口名.方法名来调用,且可以有多个static方法
static===show1
3、总结
只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现
二、Lambda
1、函数式接口
有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为lambda表达式。
public class Test {
public static void main(String[] args) {
Animal animal = () -> System.out.println("eat");
animal.eat();
Animal.show();
Animal.show1();
animal.show2();
}
}
@FunctionalInterface
interface Animal {
void eat();
static void show() {
System.out.println("static===show===接口的static方法只能使用接口名.方法名来调用,且可以有多个static方法");
}
static void show1() {
System.out.println("static===show1");
}
default void show2() {
System.out.println("default===show2===接口有且只能有一个default方法");
}
}
2、FunctionalInterface
@FunctionalInterface检测接口是否属于函数式接口
三、Lambda和匿名内部类在使用上的区别
1、所需的类型不一样
匿名内部类,需要的类型可以是抽象类、接口
Lambda表达式需要的类型必须是接口
2、抽象方法的数量不一样
匿名内部类所需的接口中抽象方法的数量随意
Lambda表达式所需的接口只能有一个抽象方法
3、实现原理不同
匿名内部类在编译后会形成class
Lambda表达式时在程序运行的时候生成class
四、常用接口
1、Supplier——无参有返回值
.get
2、Comsumer——有参无返回值
.accept
.andThen
3、Function——一个参数,一个返回值
.apply
.andThen
4、Predicate——一个参数,返回boolean
.test
.and
.or
import cn.hutool.core.date.DateUtil;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class Test {
public static void main(String[] args) {
testOfSupplier(() -> DateUtil.now());
testOfConsumer(str -> System.out.println(Integer.parseInt(str)), "1024");
testOfConsumer(str -> System.out.print("consumer-" + str), str -> System.out.println("===consumer2-" + str), "hello");
testOfFunction(num -> "===入参:" + num + "===运算后的返回值:" + num * 5, 12);
testOfFunction(num -> "Hello" + num, str -> str.length(), 12);
testOfPredicate(num -> num > 12, 11);
testOfPredicate2(num -> num > 12, 11);
testOfPredicate(num -> num > 10, num -> num < 20, 12);
testOfPredicate(num -> num > 10, num -> num > 20, 12);
}
public static void testOfSupplier(Supplier<String> supplier) {
System.out.println("===Supplier.get===:" + supplier.get());
}
public static void testOfConsumer(Consumer<String> consumer, String str) {
System.out.print("===Consumer.accept===:");
consumer.accept(str);
}
public static void testOfConsumer(Consumer<String> consumer, Consumer<String> consumer2, String str) {
System.out.print("===Consumer.andThen===:");
consumer.andThen(consumer2).accept(str);
}
public static void testOfFunction(Function<Integer, String> function, Integer num) {
System.out.println("===Function.apply===:" + function.apply(num));
}
public static void testOfFunction(Function<Integer, String> function, Function<String, Integer> function2, Integer num) {
System.out.println("===Function.andThen===:" + function.andThen(function2).apply(num));
}
public static void testOfPredicate(Predicate<Integer> predicate, Integer num) {
System.out.println("===Predicate.test===:" + predicate.test(num));
}
public static void testOfPredicate2(Predicate<Integer> predicate, Integer num) {
System.out.println("===Predicate.negate===:" + predicate.negate().test(num));
}
public static void testOfPredicate(Predicate<Integer> predicate, Predicate<Integer> predicate2, Integer num) {
System.out.println("===Predicate.and===num:" + num + "==是否大于10小于20:" + predicate.and(predicate2).test(num));
}
public static void testOfPredicate2(Predicate<Integer> predicate, Predicate<Integer> predicate2, Integer num) {
System.out.println("===Predicate.or===num:" + num + "==是否小于10或大于20:" + predicate.or(predicate2).test(num));
}
}
五、方法引用的格式
1、应用场景:
如果Lambda所要实现的方案,已经有其他方法存在的方案,那么那么可以使用方法引用。
2、方法引用有以下几种格式
1、instaceName::methoidName 实例::方法名
2、ClassName::staticMethodName 类名::静态方法
3、ClassName::methoidName 类名::普通方法 例如String
4、Class::new 类名::new 调用的构造器
5、TypeName[]::new
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class Test2 {
public static void main(String[] args) {
Test2 test2 = new Test2();
int[] arr = {1, 2, 3, 4};
test2.show(arr);
Consumer<int[]> consumer = new Consumer<int[]>() {
@Override
public void accept(int[] ints) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("arr:" + Arrays.toString(arr) + "===sum:" + sum);
}
};
consumer.accept(arr);
Consumer<int[]> consumer2 = test2::show;
consumer2.accept(arr);
System.out.println(Test2.staticMethod("10"));
Function<String, Integer> function = str -> {
int i = Integer.parseInt(str);
System.out.print("入参num:" + str + "转换后结果为===");
return i * 20;
};
System.out.println(function.apply("20"));
Function<String, Integer> function2 = Test2::staticMethod;
System.out.println(function2.apply("20"));
Supplier<Cat> supplier = () -> new Cat("小花", 12);
System.out.println(supplier.get());
Supplier<Cat> supplier2 = Cat::new;
System.out.println(supplier2.get());
Function<Integer, int[]> function1 = int[]::new;
System.out.println(Arrays.toString(function1.apply(10)));
}
public void show(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("arr:" + Arrays.toString(arr) + "===sum:" + sum);
Function<String, Integer> function = String::length;
}
public void showCatName(Cat cat) {
System.out.println("===" + cat.getName());
}
public static Integer staticMethod(String num) {
int i = Integer.parseInt(num);
System.out.print("入参num:" + num + "转换后结果为===");
return i * 20;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Cat {
private String name;
private Integer age;
}