Java8特性: Lamda
Posted 唐微港
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8特性: Lamda相关的知识,希望对你有一定的参考价值。
函数式接口
函数式接口定义
-
只包含一个抽象方法;
-
可以包含非抽象方法;
-
最好用注解“@FunctionalInterface”保证抽象方法的唯一性。
例如:以下接口
public interface FunctionInterfaceTest<T, R> {
//唯一的抽象方法
R getSum(T a);
//Java8中允许接口中有静态的实现方法
static <T> DemoTest<T, T> getInstance() {
return t -> t;
}
static DemoTest<Integer, Integer> getInstance2() {
return t -> {
t *= 6;
return t + 1;
};
}
}
注意:
- Java8中允许接口中有静态的实现方法
- 接口中允许有一个default的默认实现方法
Java8 内置函数式接口
Consumer : 消费型接口,void accept(T t)
Supplier : 供给型接口,T get();
Function<T, R> : 函数型接口,R apply(T t);
Predicate : 断言型接口,boolean test(T t);
Lamada表达时
lamada表达时使用需要借助于函数式接口
Lamada表达式说明
-
左侧:指定了Lambda表达式需要的所有参数
-
右侧:指定了Lambda体,即lambda表达式要执行的功能,类似于方法体
-
类型,参数类型可以省略不写,jvm会自动推导
注意事项
-
左侧只有一个参数时可以不写小括号()
-
右侧只有一条语句时可以不写大括号{ }
-
参数类型和返回类型也可以省略,jvm会帮助自动推导
Lamada语法形式(实现自定义函数式接口)
-
定义多个函数式接口,后面的Lambda说明也使用这些函数式接口
/**无参无返回值*/
@FunctionalInterface
public interface DefineInterface {
void method();
}
/**一个有参数无返回*/
@FunctionalInterface
public interface DefineInterface {
void method(int a);
}
/**多参数无返回*/
@FunctionalInterface
public interface DefineInterface {
void method(int a, int b);
}
/*** 无参有返回*/
@FunctionalInterface
public interface DefineInterface {
int method();
}
/**一个参数有返回值*/
@FunctionalInterface
public interface DefineInterface {
int method(int a);
}
/**多个参数有返回值*/
@FunctionalInterface
public interface DefineInterface {
int method(int a, int b);
}
- 左边只有一个参数时可以省略()不写
- 右边只有一条语句时可以省略{ }不写
public static void main(String[] args) {
//无参无返回
DefineInterface df = () -> {
System.out.println("df");
};
df.method();
//一个参数无返回
DefineInterface df = (a) -> {
System.out.println("df param:" + a);
};
df.method(6);
//多个参数无返回
DefineInterface df = (a,b) -> {
System.out.println("df param:" + "{" + a +"," + + b +"}");
};
df.method(6, 8);
//无参有返回值
DefineInterface df = () -> {
System.out.print("df");
return 1;
};
int res = df.method();
System.out.println("return:" + res);
//一个参数有返回值
DefineInterface df = (int a) -> {
System.out.println("df param:" + a);
return 1;
};
int res2 = df.method(6);
System.out.println("return:" + res2);
//多个参数有返回值
DefineInterface df = (int a, int b) -> {
System.out.println("df param:" + "{" + a + "," + b +"}");
return 1;
};
int res3 = df.method(6, 8);
System.out.println("return:" + res3);
}
Lamada表达式引用方法(指向已实现的方法)
有时候我们不一定要自己重写某个匿名内部类的方法,我们可以利用 lambda表达式的接口快速指向一个已经被实现的方法
语法
方法归属者::方法名
静态方法的归属者为类名
普通方法归属者为对象
public class Exe1 {
/**
* 要求
* 1.参数数量和类型要与接口中定义的一致
* 2.返回值类型要与接口中定义的一致
*/
public static int doubleNum(int a) {
return a * 2;
}
public int addTwo(int a) {
return a + 2;
}
public static void main(String[] args) {
//方式一:Lamad直接指向方法
ReturnOneParam lambda1 = a -> doubleNum(a);
System.out.println(lambda1.method(3));
//方式二:::静态传递 lambda2 引用了已经实现的 doubleNum 方法(静态用方法名)
ReturnOneParam lambda2 = Exe1::doubleNum;
System.out.println(lambda2.method(3));
Exe1 exe = new Exe1();
//方式二:::静态传递 lambda4 引用了已经实现的 addTwo 方法(非静态用对象名)
ReturnOneParam lambda4 = exe::addTwo;
System.out.println(lambda4.method(2));
}
}
Lambda表达式创建线程
public class LamadaSTD {
public static void main(String[] args) {
Thread t = new Thread(() -> {
for (int i = 1; i <= 10; i++) {
System.out.println( "线程" + i);
}
});
t.start();
}
}
Lambda表达式遍历集合
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 1,2,3,4,5);
//lambda表达式 方法引用传递
list.forEach(System.out::println);
//lambda表达式 方法引用
list.forEach(element -> {
System.out.print(element);
});
}
Lambda闭包问题
把注释放开会报错,告诉我 num 值是 final 不能被改变。这里我们虽然没有标识 num 类型为 final,但是在编译期间虚拟机会帮我们加上 final 修饰关键字。
public static void main(String[] args) {
int num = 10;
Consumer<String> consumer = ele -> {
System.out.println(num);
};
//这里的注释不能打开上面Lambda表达式中的num会提示错误
//num = num + 2;
consumer.accept("hello");
}
可参考:
https://www.cnblogs.com/haixiang/p/11029639.html
以上是关于Java8特性: Lamda的主要内容,如果未能解决你的问题,请参考以下文章