关于java:学会lambda表达式能让你少敲1000行代码

5次阅读

共计 5945 个字符,预计需要花费 15 分钟才能阅读完成。

什么是 lambda 表达式

在聊起 lambda 表达式之前,咱们不得不提起函数式接口:一个接口只蕴含惟一的办法,那么它就是函数式接口。例如:

public class LambdaTest {public static void main(String[] args) {Lambda lambda=new SonLambda();
        lambda.say();}
}
//1. 一个接口只蕴含一个办法就是函数式接口
interface Lambda {void say();
}
//2. 一个类实现接口,要重写这个接口的所有办法
class SonLambda implements Lambda {
    @Override
    public void say() {System.out.println("i love lambda");
    }
}

有时候太懒的话咱们会间接写一个匿名外部类。

public class LambdaTest {public static void main(String[] args) {
        //2. 匿名外部类: 没有子类,必须借助接口或者父类
        Lambda lambda=new Lambda() {
            @Override
            public void say() {System.out.println("i like lambda");
            }
        };
        lambda.say();}
}
//1. 一个接口只蕴含一个办法就是函数式接口
interface Lambda {void say();
}
然而咱们写代码必定是越懒 (简略) 越好,这个时候 Lambda 表达式闪亮退场。
Lambda 表达式 是 Java8 公布的最重要的新个性,它的呈现就是为了解决匿名外部类那一坨坨代码的问题,让代码看起来更简洁。
lambda 表达式的语法格局如下:
(parameters) -> expression
或者
(parameters) ->{statements;}
parameters 是参数,expression 是表达式。
对于下面例子中的匿名外部类,咱们用 Lambda 表达式该怎么示意呢?
因为下面例子中匿名外部类只有一个办法,所以咱们能够省略掉它的接口名和办法名。
又因为没有参数,所以咱们间接能够用一个中括号示意它的办法名,而后用 -> 指向它的办法体。如下所示:() -> {}代替了匿名外部类。
public class LambdaTest {public static void main(String[] args) {Lambda lambda=()->{System.out.println("i like lombda");
        };
        lambda.say();}
}
//1. 一个接口只蕴含一个办法就是函数式接口
interface Lambda {void say();
}
那么你可能会问,带有参数的接口用 lambda 表达式该怎么示意呢?如下所示:
    public static void main(String[] args) {Lambda lambda=(a,b)->{System.out.println("a="+a+"b="+b);
        };
        lambda.say(1,2);
    }
}
//1 一个接口只蕴含一个办法就是函数式接口
interface Lambda {void say(int a,int b);
}

Lambda 表达式罕用办法

  1. forEach 遍历汇合中的元素
List<String> fruits= Arrays.asList("apple", "orange", "banana");
fruits.forEach(fruit->{System.out.println("水果:"+fruit);
      });


2. stream 流

Java8 中的 stream 是对汇合性能的加强,它专一于对汇合进行各种十分便当、高效的聚合操作, 或者大批量数据操作。

3. map()

获取汇合中的某一个元素,返回新的汇合。记住应用 map 之前首先要取得汇合的 stream 流。

public class LambdaTest {public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌",25));
        list.add(new User(2,"张无忌",24));
        list.add(new User(3,"周芷若",23));
        // 获取这三个人的所有名字
        Set<String> set = list.stream().map(User::getName).collect(Collectors.toSet());
        // 遍历所有人的名字
        set.forEach(name->{System.out.println("不反复的名字:"+name);
        });
    }
}


5. distinct() 去重

public class LambdaTest {public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌 01",25));
        list.add(new User(2,"张无忌 01",24));
        list.add(new User(3,"赵敏",23));
        // 获取这三个人的所有名字
        List<String> nameList = list.stream().map(User::getName).distinct().collect(Collectors.toList());
        // 遍历所有人的名字
        nameList.forEach(name->{System.out.println("去重之后的名字:"+name);
        });
    }
}

  1. reduce():将元素中的值以某种形式连接起来,SQL 中相似 sum()、avg() 或者 count() 的汇集函数,实际上就是 reduce 操作,因为它们接管多个值并返回一个值。
public class LambdaTest {public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌",25));![image](/img/bVcNopH)
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"赵敏",23));
        //1. 获取这三个人的年龄之和
        //2.map(w -> w.getAge()) 获取每一个人的年龄
        //3.reduce((x, y) -> x + y) 将他们的年龄相加
        //4.get() 获取最初的后果
        Integer sumAge = list.stream().map(w -> w.getAge()).reduce((x, y) -> x + y).get();
        System.out.println("这三个人的年龄之和:"+sumAge);
    }
}


7. match 用法

allMatch():查看是否匹配所有元素

anyMatch(): 查看是否匹配任意元素

noneMatch(): 查看是否没有匹配元素

public class LambdaTest {public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"赵敏",23));
        boolean result01 = list.stream().allMatch(w->w.getAge()>23);
        boolean result02= list.stream().anyMatch(w->w.getAge()>23);
        boolean result03= list.stream().noneMatch(w->w.getAge()>23);
        System.out.println("所有人都大于 23 岁吗?:"+result01);
        System.out.println("有大于 23 岁的吗?:"+result02);
        System.out.println("他们没有大于 23 岁的吗?:"+result03);
    }
}


8. filter() 条件过滤

 public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"赵敏",23));
 //1.filter(w -> w.getAge() > 23) 年龄大于 23
        //2.map(w -> w.getName()) 获取人的名字
        //3. 获取这三个人中年龄大于 23 岁的人的名字的汇合
        List<String> nameList = list.stream().filter(w -> w.getAge() > 23).map(w -> w.getName()).collect(Collectors.toList());
        nameList.forEach(name->{System.out.println("年龄大于 23 岁的人:"+name);
        });
    }


9. sorted() 排序

 public static void main(String[] args) {
        // 新增三个人的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"张无忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"赵敏",23));
 //1.sorted(Comparator.comparing(User::getAge)) 依据某个字段排序
        //2.reversed() 从大到小排序
        List<User> users1 = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
        System.out.println("------------- 年龄从小到大排序");
        users1.forEach(user->{System.out.println(user.getName()+" "+user.getAge());
        });
        System.out.println("------------- 年龄从大到小排序");
        List<User> users2 = list.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        users2.forEach(user->{System.out.println(user.getName()+" "+user.getAge());
        });
    }

Lambda 表达式常见案例

案例一:获取所有用户的 ID。

List<Integer> ids = list.stream().map(w -> w.getId()).collect(Collectors.toList());

案例二:将所有用户的 ID 作为 key,name 作为 value 放到一个 map 外面。

Map<Integer, String> userMap = list.stream().collect(Collectors.toMap(User::getId,User::getName));

案例三:应用 stream 转换为汇合,咱们再也不必一个个去 add 了。

List<User> users = Stream.of(user1, user2, user3).collect(Collectors.toList());

案例四:map 对象转换,咱们个别从数据库查数据为 PO 对象,返回给 web 端时个别为 VO 对象,那么这其中就波及对象转换返回,map 就提供了便当的操作。

List<UserVo> userVos = userList.stream().map(user -> {UserVo userVo = new UserVo();
    BeanUtils.copyProperties(user, userVo);
    return userVo;
}).collect(Collectors.toList());

案例五:依照某一个属性进行分组,比方这里咱们依照用户性别进行分组。

Map<Integer, List<User>> genderGroup = userList.stream().collect(Collectors.groupingBy(User::getSex, Collectors.toList()));

案例六:求最小、最大、平均值、求和。

int min = userList.stream().mapToInt(User::getAge).min().orElse(-1);
int max = userList.stream().mapToInt(User::getAge).max().orElse(-1);
int sum = userList.stream().mapToInt(User::getAge).sum();
double average = userList.stream().mapToInt(User::getAge).average().orElse(-1);

写到最初

留神:lambda 表达式有个限度,那就是只能援用 final 或 final 局部变量,这就是说不能在 lambda 外部批改定义在域外的变量, 不然会报错。

来自微信公众号“eclipse 编程”

正文完
 0