初次写,写的不好,主要是记录自己学习的点点滴滴
Lambda表达式需要满足以下两点:
1使用Lambda必须要有接口,并且该接口类只有一个抽象方法
2必须有上下文环境,才能推导出Lambda对应的接口
- 根据局部变量的赋值得知Lambda对应的接口
Runnable r = () -> System.out.println(“Lambda表达式”); - 根据调用方法的参数得知Lambda对应的接口
new Thread(() -> System.out.println(“Lambda表达式”)).start();
Lambda表达式的格式:
(形式参数)->{代码块}
形式参数:如果有多个参数,参数之间用逗号隔开,如果没有参数,直接留空就可以了
->: 指向动作(指向代码块)
{代码块}:是我们具体实现接口的内容;
下面我们拿一个Java API的线程来举例;
例:
//创建一个匿名类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名类多线程启动了");
}
}).start();
//Lambda表达式
new Thread(() ->{
System.out.println("表达式-多线程启动了");
}).start();
//优化表达式
new Thread(() -> System.out.println("优化后表达式-多线程启动了")).start();
}
得到的结果:
匿名类多线程启动了
表达式-多线程启动了
优化后表达式-多线程启动了
带参举例:
public static void main( String[] args ) {
//接口带了一个参的 ,直接在表达式括号中将属性传递进去就可以了
test(( String s ) -> {
System.out.println(s);
});
//优化Lambda表达式
test(s-> System.out.println(s));
}
//创建一个静态方法来运行
public static void test( A a ) {
a.method("天空一片云...");
}
interface A {
void method( String s );
}
Lambda表达式的省略模式
省略规则
参数类型可以省略,但是有多个参数的情况下,不能只省列一个
如果参数有且仅有一个,那么小括号可以省略,
如果代码块的语句只有一条,那么可以省略大括号和分好,如果有return关键字也必须省略掉
public static void main( String[] args ) {
lambdaAdd(new B() {
@Override
public int add( String s, String y ) {
/*Integer s1 = Integer.valueOf(s);
Integer s2 = Integer.valueOf(y);*/
return Integer.valueOf(s)+Integer.valueOf(y);//可以直接优化成一句代码
}
});
System.out.println("------------------");
//用Lambda表达式优化
lambdaAdd((s,y)->Integer.valueOf(s)+Integer.valueOf(y));
}
public static void lambdaAdd( B b ) {
int add = b.add("100", "20");//传递2个值进去
System.out.println(add);//得出的结果是 s+y
}
interface B{
int add( String s, String y );
}
接口更新三种方法
现在在接口中可以,添加default默认方法和,static 静态方法和private方法,从而不影响接口实现类(接口实现类不用实现接口方法,需要在去实现)
- 常量
public static final - 抽象方法
public abstract - 默认方法(Java 8) default void method(){}
- 静态方法(Java 8) static void method(){}; 静态方法必须用类名调取
- 私有方法(Java 9):private void method(){};
注意事项- 默认方法可以调用私有的静态方法和非静态方法
- 静态方法只能调用私有的静态方法
示例:
public interface A {
int method();
void method1();
default void method2() {
System.out.println("method2.default方法实现了1");
/*System.out.println("11111");
System.out.println("2222");
System.out.println("33333");*/
sendMethod(); //重复代码块可以删除替换静态方法实现代码内容
System.out.println("method2.default方法实现了");
}
default void method3() {
/*System.out.println("11111");
System.out.println("2222");
System.out.println("33333");*/
sendMethod();//重复代码块可以删除替换静态方法实现代码内容
System.out.println("method2.default方法实现了");
}
default void method4() {
/*System.out.println("11111");
System.out.println("2222");
System.out.println("33333");*/
sendMethod();//重复代码块可以删除替换静态方法实现代码内容
System.out.println("method2.default方法实现了");
}
static void method5() {
/* System.out.println("11111");
System.out.println("2222");
System.out.println("33333");*/
sendMethod();//重复代码块可以删除替换静态方法实现代码内容
System.out.println("method3.static 方法实现了");
}
static void method6() {
/*System.out.println("11111");
System.out.println("2222");
System.out.println("33333");*/
sendMethod();//重复代码块可以删除替换静态方法实现代码内容
System.out.println("method3.static 方法实现了");
}
//如果接口中有共同的代码块可以直接用静态的方法重构
static void sendMethod() {
System.out.println("11111");
System.out.println("2222");
System.out.println("33333");
}
}
实现类实现接口方法,也可不实现
/*
实现类可以实现新添加的接口方法,也可以不用实现,根据需求添加
*/
public class AImpl implements A {
@Override
public int method() {
return 0;
}
@Override
public void method1() {
System.out.println("method1+AImpl 方法实现了");
}
@Override
public void method2() {
System.out.println("method2,default 方法重写了");
}
}
方法引用一共有4种
方法引用的用处: 对Lambda表达式在某种情况下进行代码的优化
将Lambda表达式,改为方法引用
1.先判断Lambda表达式是否符合下面的四种情况任何一种就可以更改为方法引用
第一种:引用类方法
1.什么时候可以将lambda表达式改为引用类方法?
当Lambda表达式中类直接调用静态方法,将Lambda表达式的所有参数都传进到静态方法中.
2.使用引用类方法,参数是如何传递?
将lambda表达式中的所有参数全部传递到静态方法中
public static void main( String[] args ) {
//lambda表达式
test((y -> Integer.valueOf(y)));
//将表达式 改为引用类方法
test(Integer::valueOf);//Integer 是类,valueOf是静态方法
}
//静态方法
private static void test(Etable e) {
int week = e.week("100");
System.out.println(week);//结果为100
}
//接口
interface Etable {
int week( String y );
}
第二种引用对象方法
引用对象的实例方法,其实就引用类中的成员方法
-
格式
对象::成员方法public static void main( String[] args ) {
//Lambda表达式
lowTest(s -> s.toLowerCase());
//将Lambda表达式改为引用对象方法
ObjectMethod obj = new ObjectMethod();
lowTest(obj::low);
}
//静态方法
public static void lowTest( Etable e ) {
e.lowMethod(“HelloWorld”);
}
}
//接口
interface Etable {
void lowMethod( String s );
}
//方法类
class ObjectMethod {
public void low( String s ) {
String s1 = s.toLowerCase();
System.out.println(s1);
}
}
第三种引用类的方法
引用类的实例方法,其实就是引用类中的成员方法
-
格式
类名::成员方法
public static void main( String[] args ) {
//Lambda表达式
test((s,x,y)->{
return s.substring(x, y);
});
//优化Lambda表达式
test((s,x,y)->s.substring(x,y));
//改成引用类的实例方法
test(String::substring);
}//静态方法 public static void test(Etable1 e) { //截取2-5的字符串 String iloveJava = e.sub("IloveJava", 2, 6); System.out.println(iloveJava); } } interface Etable1{ String sub( String name, int x, int y ); }
第四种引用构造器方法
当Lambda表达式中存在创建对象,而且对象的构造方法中的参数全部来自于Lambda表达式对象
将lambda表达式中所有参数,都传递到创建对象的构造方法中
public static void main( String[] args ) {
test((name,age)->{
return new Student(name,age);
});
/*
将表达式改为引用构造器方法
*/
test(Student::new);
}
private static void test(Etable e) {
Student s = e.week("孙悟空", 888);
System.out.println(s.getName()+","+s.getAge());
}
interface Etable {
Student week( String name ,int age);
}
static class Student{
private String name ;
private int age;
public Student() {
}
public Student( 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;
}
}