在当初学习Lambda表达式时,总是迷迷糊糊,恍恍惚惚,所以这次打算一次把自己讲明白。
内部类
为什么会有内部类?
场景:如果一个类只在另一个类中使用,并且需要直接访问外部类的成员,(包括私有成员),而不需要通过 getter
或 setter
方法。
例如Node
类通常只在 LinkedList
类中使用。
一些好处:
- 实现多重继承
- Java本身不支持多重继承,但是可以在类中创建多个内部类,继承不同的类
匿名内部类
- 没有显式的类名,直接通过
new
关键字创建对象并实现接口或继承类。
1 2 3 4 5 6 7 8 9 10 11
| class Outer { void display() { Greeting greeting = new Greeting() { @Override public void greet() { System.out.println("Hello from anonymous class!"); } }; greeting.greet(); } }
|
场景
比如有一个接口Greeting,里面有一个方法greet,我想使用这个方法。
- 传统做法:
- 先创建一个类GreetingImpl实现这个接口,并实现接口中的greet方法,再创建这个实现类的对象,再通过对象调用这个方法。
- 匿名内部类:
- 实际上整个功能,有效的代码仅仅是重写我需要调用的方法这部分
- 可以用匿名内部类直接不实现接口,直接创建一个匿名内部类实现重写我想要调用的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| interface Greeting { void greet(); }
class GreetingImpl implements Greeting { @Override void greet(){ System.out.println("Hello from anonymous class!"); } }
public class AnonymousClassExample { public static void main(String[] args) { GreetingImpl greetingImpl = new GreetingImpl(); greetingImpl.greet(); Greeting greeting = new Greeting() { @Override public void greet() { System.out.println("Hello from anonymous class!"); } };
greeting.greet(); } }
|
Lambda表达式
进一步的,如果是函数式接口(即只有一个抽象方法的接口),可以用Lambda表达式代替
Lambda 表达式只能用于实现函数式接口(只有一个抽象方法的接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| interface Greeting { void greet(); }
class GreetingImpl implements Greeting { @Override void greet(){ System.out.println("Hello from anonymous class!"); } }
public class AnonymousClassExample { public static void main(String[] args) { GreetingImpl greetingImpl = new GreetingImpl(); greetingImpl.greet(); Greeting greeting = new Greeting() { @Override public void greet() { System.out.println("Hello from anonymous class!"); } }; Greeting greeting = () -> System.out.println("Hello from Lambda!");
greeting.greet(); } }
|
Lambda表达式还可以用作函数式编程,“传递函数”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| interface Calculator { int calculate(int a, int b); }
public class Example { public static int operate(int a, int b, Calculator calculator) { return calculator.calculate(a, b); } public static void main(String[] args){ int sum = operate(3, 5, new Calculator() { @Override public int calculate(int x, int y) { return x + y; } }); int sum = operate(3, 5, (x, y) -> x + y); } }
|
方法引用
方法引用是简化Lambda表达式,看似是传递的方法,实际上和Lambda表达式一样传递的是接口实现类的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;
public class MethodReferenceExample { public static void main(String[] args) { List<String> fruits = Arrays.asList("apple", "banana", "cherry");
List<Integer> lengths1 = fruits.stream() .map(s -> s.length()) .collect(Collectors.toList()); System.out.println(lengths1);
List<Integer> lengths2 = fruits.stream() .map(String::length) .collect(Collectors.toList()); System.out.println(lengths2); } }
|