轻松了解jdk8之lambda表达式常用API(持续更新……)


前言:这篇文章涉及的面很浅,只是总结一下jdk8推出的lambda表达式常用的一些功能,至于内部的实现原理,那是不可能的。

这两年,基本所有的公司都由之前的JDK7转战JDK8,还记得上次去饿了么面试给的面试题,第一题就是用lambda实现一个功能,当时对lambda表达式基本是零了解,然后……。现在随着慢慢的使用,也慢慢了解lambda表达式真的是一个好东西,可以大大的简化以前的代码,下面在说常用lambda表达式的时候,会附上对应之前需要的代码量。相信你也会喜欢上它的。

1. 一组对象的分组

场景:Collection下的用户对象集合,根据用户的年龄分组。

代码:

List<User> users = new ArrayList(); //假装数组中有数据
//使用lambda前
Map<Integer, List<User>> userMap = new HashMap<>();
for (User user : users) {
    List<User> innerUsers = userMap.get(user.getAge());
    if (innerUsers == null) innerUsers = new ArrayList<>();
    innerUsers.add(user);
    userMap.put(user.getAge(), innerUsers);
}
//使用lambda后
Map<Integer, List<User>> userMap = 
        users.stream().collect(Collectors.groupingBy(User::getAge));

n行代码直接简化成一行代码,爽歪歪接下来都是一行代码搞定

2. 对象集合抽取字段

场景:标题不想写太长,场景来描述。在实际开发中会经常遇到,两个表有关联,先查询一张表的数据,获取关联另一张表数据的ID集合,然后根据这个ID集合去关联表中查对应的数据。这里就要对ID集合进行抽取。

代码:

List<User> users = new ArrayList<>(); //假装数组中有数据
//使用Lambda前
Set<String> relationIds = new TreeSet<>();
for (User user : users) {
    relationIds.add(user.getRelationId());
}
//使用Lambda后
Set<String> relationIds = users.stream()
        .map(User::getRelationId).collect(Collectors.toSet());

3. 过滤数据

场景:过滤出所有年龄大于35的程序员。给这些兄弟一人送一张飞机票……

List<User> users = new ArrayList<>();//假装数组中有数据
//使用Lambda前
List<String> userList = new ArrayList<>();
for (User user : users) {
    if (Integer.compare(35, u.getAge()) < 0) {
        userList.add(user.getRelationId());
    }
}
//使用Lambda后
List<User> userList = users.stream()
        .filter(u -> Integer.compare(35, u.getAge()) < 0)
        .collect(Collectors.toList());

4. 数据排序

场景:根据用户的年龄排序,升序和降序两种。

  • 升序:
List<User> users = new ArrayList<>();//假装数组中有数据
//使用Lambda后
List<User> userList = users.stream()
        .sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
  • 降序
List<User> users = new ArrayList<>();//假装数组中有数据
//使用Lambda后
List<User> userList = users.stream()
        .sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());

这里就不具体单独的写排序逻辑啦,有点麻烦,偷懒一下~

5. 抽取对象唯一标识

这种场景出现的也比较多的,今天在做的功能就用到,刚好做个笔记。

场景:给前端一个列表,前端会对这个列表做增删改查操作。操作完成后传入后端,后端需要查询出之前给前端的列表,然后和现在的列表比对,发生哪些变动,更好的做CRUD操作。这个时候就要把给前端的列表做对象唯一标识抽取。有点抽象,看例子。

List<Article> articles = Lists.newArrayList();//查出来的文章列表
//使用lambda表达式前
Map<Long, Article> articleMap = Maps.newHashMap();
for (Article article : articles) {
    articleMap.put(article.getId(), article);
}
//使用lambda表达式后
Map<Long, Article> articleMap =
        articles.stream().collect(Collectors.toMap(Article::getId, a -> a));

List<Article> newArticles = Lists.newArrayList();//修改过的文章列表
//使用lambda表达式前
Map<Long, Article> newArticleMap = Maps.newHashMap();
for (Article article : newArticles) {
    if (article.getId() != null)
        newArticleMap.put(article.getId(), article);
}
//使用lambda表达式后
Map<Long, Article> newArticleMap = newArticles.stream()
        .filter(a -> a.getId() != null).collect(Collectors.toMap(Article::getId, a -> a));

这里其实是有一个坑的,Article::getId要唯一,否则会报Duplicate key(键重复)异常。上面也提到是唯一标识。

6. 集合求和

给定一个List集合,对List集合内的元素求和
场景:

  1. List集合内的元素的数值类型的包装类,直接怼元素进行求和
  2. List集合中是对象,需要对对象内的某个字段进行求和
// 场景1
List<Integer> intList = Lists.newArrayList();
intList.add(10);
intList.add(11);
intList.add(13);
int sum = intList.stream().mapToInt(Integer::intValue).sum();
// 场景2
List<User> userList = Lists.newArrayList();
userList.add(new User(35));
userList.add(new User(26));
userList.add(new User(47));
int sum2 = userList.stream().mapToInt(User::getAge).sum();

文章作者: 程序猿洞晓
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 程序猿洞晓 !
评论
 上一篇
参数校验之Hibernate-validator的基本使用 参数校验之Hibernate-validator的基本使用
validation-api在开发过程中是经常使用到的,特别是参数校验,刚开始做开发工作的时候,都是在Service层用if…else…来判断参数的合法性,这个会使代码显得很臃肿,后来接触validation,真的是很好用的。这里分享出来,也是做个笔记,以后用到可以作为参考资料。
2019-05-03
下一篇 
物联网(IoT)常用协议MQTT及MQTT Broker之mosquitto的基础使用 物联网(IoT)常用协议MQTT及MQTT Broker之mosquitto的基础使用
大数据、人工智能、物联网,这些都是互联网将来重点发展的规划方向。大数据分析你的行为,如在淘宝、京东上经常看或者搜一类产品,他就会在首页智能的向你推这类的丰富产品。人工智能让生活更有趣,但是人工智能目前更多的是一个噱头,发展还是有待走向成熟化的。至于物联网,现在很多公司都是有雏形产品的,一些巨头公司已经提供了对应的处理方案,如阿里……
2019-02-11
  目录