lambda表达式介绍
Lambda表达式是java8中最重要的新功能之一。使用lambda表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。lambda表达式同时还提升了对集合,框架的迭代遍历,过滤数据的操作。
lambda案例
package com.example.lambda.test1;
import org.springframework.core.convert.converter.ConvertingComparator;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* lambda表达式入门
*/
public class Test1 {
public static void main(String[] args) {
//内部类 没有使用lambda表达式之前
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("runing....");
}
});
thread.start();
//使用lambda 可以看出来使用起来是非常便捷
new Thread(() -> System.out.println("runing2....")).start();
//集合排序 没有使用前
List<String> list= Arrays.asList("java","javaScript","scala","python");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
System.out.println(list);
//使用后
Collections.sort(list,(a1,b1)->a1.length()-b1.length());
list.forEach(System.out::println);
}
}
lambda表达式的特点
1.函数式编程
2.代码简洁
3.参数类型自动推断
lambda表达式应用场景
任何有函数式接口的地方
案例
package com.example.lambda.test1;
import java.util.ArrayList;
import java.util.List;
/**
* 函数式编程理解
*/
public class Test2 {
public static void main(String[] args) {
ArrayList<Student> list=new ArrayList<>();
list.add(new Student("zhangsan",12,33));
list.add(new Student("lisi",13,37));
list.add(new Student("wangwu",14,23));
list.add(new Student("mayi",16,13));
list.add(new Student("liuliu",26,93));
list.add(new Student("wangzha",16,99));
list.add(new Student("runtu",13,76));
//查找年龄大于14的学生
queryGetAge(list);
//查找分数大于75的学生
queryGetScore(list);
System.out.println("---------------------------------------");
queryGetAge1(list,new AgeFileter());
queryGetScore1(list,new scoreFileter());
//内部类实现
queryGetAge1(list, new StudentFileter() {
@Override
public boolean compareStudent(Student student) {
return student.getAge()>14;
}
});
queryGetScore1(list, new StudentFileter() {
@Override
public boolean compareStudent(Student student) {
return student.getScore()>75;
}
});
//引入lambda
queryGetScore1(list,(e) ->e.getScore()>75);
queryGetAge1(list,(e) -> e.getAge()>14);
}
/**
* 常规写法1
*/
public static void queryGetAge(List<Student> list){
List<Student> lists=new ArrayList<>();
for (Student stu:list){
//大于14岁 并且根据姓名去重
if(stu.getAge()>14 && !list.contains(stu.getName())){
lists.add(stu);
}
}
System.out.println(lists);
}
/**
* 常规写法1
*/
public static void queryGetScore(List<Student> list){
List<Student> lists=new ArrayList<>();
for (Student stu:list){
//成绩大于75 并且根据姓名去重
if(stu.getScore()>75 && !list.contains(stu.getName())){
lists.add(stu);
}
}
System.out.println(lists);
}
/**
* 接口写法1
*/
public static void queryGetAge1(List<Student> list,StudentFileter fileter){
List<Student> lists=new ArrayList<>();
for (Student stu:list){
//大于14岁 并且根据姓名去重
if(fileter.compareStudent(stu)){
lists.add(stu);
}
}
System.out.println(lists);
}
/**
* 接口写法1
*/
public static void queryGetScore1(List<Student> list,StudentFileter fileter){
List<Student> lists=new ArrayList<>();
for (Student stu:list){
//成绩大于75 并且根据姓名去重
if(fileter.compareStudent(stu)){
lists.add(stu);
}
}
System.out.println(lists);
}
}
/**
* 接口写法
*/
interface StudentFileter{
//比较返回布尔
public boolean compareStudent(Student student);
}
/**
* 继承接口
*/
class AgeFileter implements StudentFileter{
@Override
public boolean compareStudent(Student student) {
return student.getAge()>14;
}
}
class scoreFileter implements StudentFileter{
@Override
public boolean compareStudent(Student student) {
return student.getScore()>75;
}
}
/**
* 实体类
*/
class Student{
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
super();
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score='" + score + '\'' +
'}';
}
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;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
什么是函数式接口?
只有一个抽象方法的接口(除了OBJECT类方法)叫做函数式接口
例子
package com.example.lambda.test1;
/**
* 函数式接口
*/
//使用注解校验
@FunctionalInterface
public interface Test3 {
public void add();
//public void update(); 两个接口添加 注解
}
函数式接口 常用API
supplier 代表一个输出
Consumer 代表一个输入
biConsumer 代表两个输入
Function 代表一个输入,一个输出(一般输入和输出是不同类型的)
UnaryOperator 代表一个输入,一个输出(输入和输出是相同类型的)
BiFunction 代表两个输入,一个输出(一般输入和输出是不同类型的)
binaryOperator 代表两个输入,一个输出(输入和输出是相同类型的)
package com.example.lambda.test1;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* lambda
*/
public class Test4 {
public static void main(String[] args) {
//一个输入输出
Function<String,Integer> f1=(str)->{return str.length();};
System.out.println(f1.apply("abcdefg"));
//一个输出
Supplier<String> f2=() -> {return "ss1s";};
System.out.println(f2.get());
Consumer<String> f3=(str) -> System.out.println(str);
f3.accept("sss");
//代表两个输入,一个输出(一般输入和输出是不同类型的)
BiFunction<String,String,Integer> bf=(a,b)->a.length()+b.length();
System.out.println(bf.apply("1111","2222"));
System.out.println("----------------------");
Runnable runnable1=() ->get();
}
static int get(){
return 1;
}
static String find(){
return "find";
}
}
方法引用
方法引用是用来直接访问类火灾实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以是偶男调用另外一个方法类实现,就有可能可以使用方法引用;
package com.example.lambda.test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 方法引用
*/
public class Test5 {
public static void main(String[] args) {
// List<String> list= Arrays.asList("a","b","c","d","e");
// list.forEach(System.out::println);
//
// Function<String,Integer> f1=(str)->{return str.length();};
// System.out.println(f1.apply("11111"));
//
// Consumer<String> c=(s)-> System.out.println(s);
// c.accept("s");
//常规调用
System.out.println(put());
//lambda使用
Supplier<String> put=()->put();
System.out.println(put.get());
//方法引用 静态方法引用 类名::+方法名
Supplier<String> put1=Test5::put;
System.out.println(put1.get());
Supplier<String> tt =Fun::tt;
System.out.println(tt.get());
System.out.println("-------------------------");
Function<String,String> str=(s)->s.toUpperCase();
Function<String,String> f1=Test5::toUpdate;
System.out.println(str.apply("abc"));
System.out.println(f1.apply("abc"));
}
public static String put(){
System.out.println("put....");
return "put";
}
public static String toUpdate(String str){
return str;
}
}
class Fun{
public static String tt(){
System.out.println("tt");
return "tt";
}
}
静态方法引用:如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用
实例方法引用:如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
对象方法引用:抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数,如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
构造方法引用:如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
package com.example.lambda.test1;
import java.util.function.Supplier;
/**
* 方法引用
* 实例方法引用
*/
public class Test6 {
public String put(){
return "put";
}
public static void main(String[] args) {
//普通调用
System.out.println(new Test6().put());
//lambda调用
Supplier<String> s1=()->new Test6().put();
Supplier<String> s2=new Test6()::put;
System.out.println(s1.get());
System.out.println(s2.get());
}
}