Lambda表达式
-
Lambda表达式的使用条件:
1、Lambda必须是接口类型。
2、接口中有且仅有一个抽象方法。 -
语法:(方法的参数列表)->{方法体}
-
简化方式:
1、任何情况下,参数类型可以省略
2、如果参数列表有且仅有一个参数,()可以省略;
3、如果方法体中有且仅有一条语句,那么{}和;一起省略,如果有return,return也要一起省略。 -
Lambda表达式的好处:
简化匿名内部类的书写。 -
Lambda表达式和匿名内部类的区别?
1、能使用Lambda表达式的地方就可以使用匿名内部类;能使用匿名内部类的地方不一定可以使用Lambda表达式。
2、匿名内部类编译之后有class文件,Lambda表达式编译之后没有class文件。
案例1
package com.jxufe_ldl.class01.test02;
public interface Flyable {
void fly(String s);
}
package com.jxufe_ldl.class01.test02;
public class FlyableDemo {
public static void main(String[] args) {
useflyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
System.out.println("--------");
useflyable((String s) -> {
System.out.println(s);
System.out.println("我想和你去旅行");
});
}
private static void useflyable(Flyable a) {
a.fly("风和日丽,晴空万里");
}
}
案例2:接口中的方法带参数和返回值
package com.jxufe_ldl.class01.test03;
public interface Addable {
int add(int x, int y);
}
package com.jxufe_ldl.class01.test03;
public class AddableDemo {
public static void main(String[] args) {
useaddable((int x, int y) -> {
return x + y;
});
}
private static void useaddable(Addable a) {
int sum = a.add(30, 40);
System.out.println("sum = " + sum);
}
}
案例3:
package com.jxufe_ldl.class01.test05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class ListDemo {
public static void main(String[] args) {
// 创建一个List集合,添加元素
List<Integer> lt = List.of(20,43,12,87,45,6,78,42,66);
List<Integer> list = new ArrayList<Integer>(lt);
// 对集合中的元素降序排序
Collections.sort(list, (o1, o2) -> o2 - o1);
/*Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});*/
// 遍历集合
// System.out.println(list);
/*list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
integer *= 2;
System.out.println(integer);
}
});*/
list.forEach(integer -> System.out.print(integer + " "));
}
}
接口
掌握:接口中除了可以定义常量和抽象方法之外,开可以定义默认方法、静态方法、私有方法。
-
默认方法:
语法:public default 返回值类型 方法名(参数列表){} //public可以省略
注意:默认方法可以被重写,如果实现类重写了默认方法,那么就是调用重写的方法。重写的默认方法没有default关键字。 -
静态方法:
语法: public static 返回值类型 方法名(参数列表){} //public可以省略
注意:静态方法不能被重写,只能使用接口名调用,不能使用实现类名或者实现类的对象调用。 -
私有方法:
语法1: private 返回值类型 方法名(参数列表){}
语法2: private static 返回值类型 方法名(参数列表){}
注意:私有的方法只能在接口内部访问,外面(包括实现类)无法访问私有方法。
package com.jxufe_ldl.class02;
public interface Inter extends Inter2 {
// 抽象方法
void show();
// 默认方法,可以调用普通私有方法和静态私有方法
default void defaultMethood() {
System.out.println("接口中的默认方法");
mehtod1();
}
// 静态方法,只能调用静态的私有方法
static void method() {
System.out.println("接口中的静态方法");
method2();
}
// 普通的私有方法
private void mehtod1() {
System.out.println("普通的私有方法");
}
// 静态的私有方法
private static void method2() {
System.out.println("静态的私有方法");
}
}
package com.jxufe_ldl.class02;
public interface Inter2 {
void show2();
}
package com.jxufe_ldl.class02;
public class InterImp implements Inter {
@Override
public void show() {
System.out.println("重写的show方法");
}
@Override
public void show2() {
System.out.println("重写Inter中继承的show2方法");
}
}
package com.jxufe_ldl.class02;
public class InterDemo {
public static void main(String[] args) {
// 用多肽的方式创建接口对象
Inter i = new InterImp();
// 接口中的抽象方法
i.show();
i.show2();
// 接口中的默认方法
i.defaultMethood();
// 接口中的静态方法只能通过接口名的方式调用
Inter.method();
}
}
方法引用
-
方法引用的使用场景:
在Lambda表达式中,如果方法体仅有一条语句,并且符合 对象.方法()、类名.方法()、new 类名()…那么可以使用方法引用来代替Lambda表达式注意:如果Lambda表达式的参数列表有参数,那么引用的方法也必须能接收这个参数。
-
方法引用的格式:
对象.方法()----->对象::方法名 注意:不需要();
类名.方法()----->类名::方法名
new 类名()----->类名::new
package com.jxufe_ldl.class03.test01;
public interface InterPrint {
int prnitNumber(int x);
}
package com.jxufe_ldl.class03.test01;
public class PrintDemo {
public static void main(String[] args) {
usePrintNumber(num -> Math.abs(num));
System.out.println("--------");
usePrintNumber(Math::abs);
}
private static void usePrintNumber(InterPrint i) {
int num = i.prnitNumber(-10);
System.out.println(num);
}
}
案例2:
package com.jxufe_ldl.class03.test02;
public interface Converter {
int convert(String s);
}
:package com.jxufe_ldl.class03.test02;
public class ConverterDemo {
public static void main(String[] args) {
// Lambda表达式
useConverter(s -> Integer.parseInt(s));
// 引用类方法
useConverter(Integer::parseInt);
}
private static void useConverter(Converter c) {
int num = c.convert("666");
System.out.println(num);
}
}
案例3:
package com.jxufe_ldl.class03.test03;
public interface MySubstring {
String mysub(String s, int x, int y);
}
package com.jxufe_ldl.class03.test03;
public class MySubstringDemo {
public static void main(String[] args) {
// Lambda表达式
/*useMySubstring( (String s, int x, int y) -> {
return s.substring(x, y);
} );*/
useMySubstring( (s, x, y) -> s.substring(x, y));
// 类的实例方法引用
useMySubstring(String::substring);
}
private static void useMySubstring(MySubstring ms) {
String s = ms.mysub("helloworld", 2, 5);
System.out.println(s);
}
}
Lambda表达式
Lambda表达式的使用条件:
1、Lambda必须是接口类型。
2、接口中有且仅有一个抽象方法。
语法:(方法的参数列表)->{方法体}
简化方式:
1、任何情况下,参数类型可以省略
2、如果参数列表有且仅有一个参数,()可以省略;
3、如果方法体中有且仅有一条语句,那么{}和;一起省略,如果有return,return也要一起省略。
Lambda表达式的好处:
简化匿名内部类的书写。
Lambda表达式和匿名内部类的区别?
1、能使用Lambda表达式的地方就可以使用匿名内部类;能使用匿名内部类的地方不一定可以使用Lambda表达式。
2、匿名内部类编译之后有class文件,Lambda表达式编译之后没有class文件。
案例1
package com.jxufe_ldl.class01.test02;
public interface Flyable {
void fly(String s);
}
package com.jxufe_ldl.class01.test02;
public class FlyableDemo {
public static void main(String[] args) {
useflyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
System.out.println("--------");
useflyable((String s) -> {
System.out.println(s);
System.out.println("我想和你去旅行");
});
}
private static void useflyable(Flyable a) {
a.fly("风和日丽,晴空万里");
}
}
案例2:接口中的方法带参数和返回值
package com.jxufe_ldl.class01.test03;
public interface Addable {
int add(int x, int y);
}
package com.jxufe_ldl.class01.test03;
public class AddableDemo {
public static void main(String[] args) {
useaddable((int x, int y) -> {
return x + y;
});
}
private static void useaddable(Addable a) {
int sum = a.add(30, 40);
System.out.println("sum = " + sum);
}
}
案例3:
package com.jxufe_ldl.class01.test05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class ListDemo {
public static void main(String[] args) {
// 创建一个List集合,添加元素
List<Integer> lt = List.of(20,43,12,87,45,6,78,42,66);
List<Integer> list = new ArrayList<Integer>(lt);
// 对集合中的元素降序排序
Collections.sort(list, (o1, o2) -> o2 - o1);
/*Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});*/
// 遍历集合
// System.out.println(list);
/*list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
integer *= 2;
System.out.println(integer);
}
});*/
list.forEach(integer -> System.out.print(integer + " "));
}
}
接口
掌握:接口中除了可以定义常量和抽象方法之外,开可以定义默认方法、静态方法、私有方法。
默认方法:
语法:public default 返回值类型 方法名(参数列表){} //public可以省略
注意:默认方法可以被重写,如果实现类重写了默认方法,那么就是调用重写的方法。重写的默认方法没有default关键字。
静态方法:
语法: public static 返回值类型 方法名(参数列表){} //public可以省略
注意:静态方法不能被重写,只能使用接口名调用,不能使用实现类名或者实现类的对象调用。
私有方法:
语法1: private 返回值类型 方法名(参数列表){}
语法2: private static 返回值类型 方法名(参数列表){}
注意:私有的方法只能在接口内部访问,外面(包括实现类)无法访问私有方法。
package com.jxufe_ldl.class02;
public interface Inter extends Inter2 {
// 抽象方法
void show();
// 默认方法,可以调用普通私有方法和静态私有方法
default void defaultMethood() {
System.out.println("接口中的默认方法");
mehtod1();
}
// 静态方法,只能调用静态的私有方法
static void method() {
System.out.println("接口中的静态方法");
method2();
}
// 普通的私有方法
private void mehtod1() {
System.out.println("普通的私有方法");
}
// 静态的私有方法
private static void method2() {
System.out.println("静态的私有方法");
}
}
package com.jxufe_ldl.class02;
public interface Inter2 {
void show2();
}
package com.jxufe_ldl.class02;
public class InterImp implements Inter {
@Override
public void show() {
System.out.println("重写的show方法");
}
@Override
public void show2() {
System.out.println("重写Inter中继承的show2方法");
}
}
package com.jxufe_ldl.class02;
public class InterDemo {
public static void main(String[] args) {
// 用多肽的方式创建接口对象
Inter i = new InterImp();
// 接口中的抽象方法
i.show();
i.show2();
// 接口中的默认方法
i.defaultMethood();
// 接口中的静态方法只能通过接口名的方式调用
Inter.method();
}
}
方法引用
方法引用的使用场景:
在Lambda表达式中,如果方法体仅有一条语句,并且符合 对象.方法()、类名.方法()、new 类名()…那么可以使用方法引用来代替Lambda表达式
注意:如果Lambda表达式的参数列表有参数,那么引用的方法也必须能接收这个参数。
方法引用的格式:
对象.方法()----->对象::方法名 注意:不需要();
类名.方法()----->类名::方法名
new 类名()----->类名::new
package com.jxufe_ldl.class03.test01;
public interface InterPrint {
int prnitNumber(int x);
}
package com.jxufe_ldl.class03.test01;
public class PrintDemo {
public static void main(String[] args) {
usePrintNumber(num -> Math.abs(num));
System.out.println("--------");
usePrintNumber(Math::abs);
}
private static void usePrintNumber(InterPrint i) {
int num = i.prnitNumber(-10);
System.out.println(num);
}
}
案例2:引用类方法
package com.jxufe_ldl.class03.test02;
public interface Converter {
int convert(String s);
}
:package com.jxufe_ldl.class03.test02;
public class ConverterDemo {
public static void main(String[] args) {
// Lambda表达式
useConverter(s -> Integer.parseInt(s));
// 引用类方法
useConverter(Integer::parseInt);
}
private static void useConverter(Converter c) {
int num = c.convert("666");
System.out.println(num);
}
}
案例3:类的实例方法引用
package com.jxufe_ldl.class03.test03;
public interface MySubstring {
String mysub(String s, int x, int y);
}
package com.jxufe_ldl.class03.test03;
public class MySubstringDemo {
public static void main(String[] args) {
// Lambda表达式
/*useMySubstring( (String s, int x, int y) -> {
return s.substring(x, y);
} );*/
useMySubstring( (s, x, y) -> s.substring(x, y));
// 类的实例方法引用
useMySubstring(String::substring);
}
private static void useMySubstring(MySubstring ms) {
String s = ms.mysub("helloworld", 2, 5);
System.out.println(s);
}
}