1、概念
lambda
是一个匿名函数
,我们可以吧lambda表达式理解为是一段可以传递的代码
(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,是java的语言表达能力得到了提升。
写法的对比
//原来的匿名内部类
@Test
public void test1(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
int compare = comparator.compare(1, 2);
System.out.println(compare);
}
//Lambda表达式
@Test
public void test2(){
Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
int compare = comparator.compare(2, 1);
System.out.println(compare);
}
2.基础语法
java8中引入了一个新的操作符“->” 该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分成两部分
左侧:Lambda 表达式的参数列表,接口中实现方法的参数列表
右侧:Lambda 表达式中所需执行的功能,即Lambda体,接口实现函数的功能
2.1 语法格式一
- 无参数,无返回值
- () -> System.out.println(“helloword!”);
@Test
public void test1(){
//原写法
Runnable run1 = new Runnable() {
@Override
public void run() {
System.out.println("HelloWord!");
}
};
run1.run();
//Lambda写法
Runnable run2 = () -> System.out.println("Lambda..HelloWorld!");
run2.run();
}
2.2 语法格式二
- 有一个参数,无返回值
- (x) -> System.out.println(x)
@Test
public void test2(){
Consumer con = (x) -> System.out.println(x);
con.accept("迪迦!");
}
2.3 语法格式三
- 若只有一个参数,无返回值,小括号可以不写
- x -> System.out.println(x)
@Test
public void test2(){
Consumer con = x -> System.out.println(x);
con.accept("迪迦!");
}
2.4 语法格式四
- 有两个以上的参数,并且Lambda体中有多条语句,Lambda必须有大括号包起来
- (o1,o2) -> {
System.out.println(“函数式接口!”);
return Integer.compare(o1,o2);
}
@Test
public void test3(){
Comparator<Integer> comparator = (o1,o2) -> {
System.out.println("函数式接口!");
return Integer.compare(o1,o2);
};
System.out.println(comparator.compare(1,2));
}
2.5 语法格式五
- 若Lambda体中只有一条语句,return 和 大括号都可以省略不写
- (o1,o2) -> Integer.compare(o1,o2)
@Test
public void test3(){
Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2);
System.out.println(comparator.compare(1,2));
}
2.6 语法格式六
- Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
- (Integer o1,Integer o2) -> Integer.compare(o1,o2)
//类型推断
String[] strs = {"aaa","bbb","ccc"};
@Test
public void test3(){
Comparator<Integer> comparator = (Integer o1,Integer o2) -> Integer.compare(o1,o2);
System.out.println(comparator.compare(1,2));
}
3.Lambda 表达式需要“函数式接口”的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionInterface
修饰可以检查是否式函数式接口
@FunctionalInterface
public interface MyInterface<T> {
public String getString(T str);
}
4、java内置四大核心函数式接口
4.1 Consumer
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
@Test
public void testConsumer(){
Consumer<Long> consumer = x -> System.out.println("迪迦抹除了" + x + "头怪兽!");
consumer.accept(5L);
}
4.2 Supplier
/**
* Gets a result.
*
* @return a result
*/
T get();
@Test
public void testSupplier(){
Supplier<String> supplier = () -> "我是迪迦!";
System.out.println(supplier.get());
}
4.3 Function<T, R>
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
@Test
public void testFunction(){
String ABC = handlerString("abc", (str) -> str.toUpperCase());
System.out.println(ABC);
}
public String handlerString(String str,Function<String,String> fun){
return fun.apply(str);
}
4.4 Predicate
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
@Test
public void testPredicate(){
List<String> list = Arrays.asList("aaa","bbbb","ccccc","dddddd");
List<String> newList = filterStringLength(list, x -> x.length() > 3);
System.out.println(newList);
}
public List<String> filterStringLength(List<String> list,Predicate<String> predicate){
List<String> newList = new ArrayList<>();
for (String str : list) {
if (predicate.test(str)){
newList.add(str);
}
}
return newList;
}
5.方法引用
- 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用是Lambda表达式的另外一种表现形式)
- 备注①:已有方法的参数列表和返回值必须与Lambda接口抽象方法的参数列表和返回值一致。
- 备注②:若Lambda 参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用
ClassName::method
5.1 对象::实例方法名
例如:accept
方法的参数和返回值与println
方法的参数和返回值一致。
void accept(T t);
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
@Test
public void test5(){
//println和
PrintStream out = System.out;
Consumer consumer = x -> System.out.println(x);
Consumer consumer1 = out::println;
Consumer consumer2 = System.out::println;
}
5.2 类::静态方法名
Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2);
Comparator<Integer> comparator1 = Integer::compareTo;
5.3 类::实例方法名
BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
biPredicate.test("a","aa");
BiPredicate<String,String> biPredicate1 = String::equals;
biPredicate1.test("a","aa");
6.构造器引用
Supplier<String> supplier = () -> new String();
Supplier<String> supplier1 = String::new;
System.out.println("supplier = " + supplier.get());
System.out.println("supplier1 = " + supplier1.get());
7.数组引用
Function<Integer,String[]> function = (x) -> new String[x];
String[] apply = function.apply(2);
System.out.println(apply.length);
Function<Integer,String[]> function1 = String[]::new;
String[] apply1 = function1.apply(3);
System.out.println(apply1.length);