Java lambda 以及 Lambda在集合中的使用

本文详细介绍了Java 8中Lambda表达式在集合操作中的使用,包括列表遍历、变换、寻找元素、挑选元素、归约和元素连接等。通过示例展示了如何使用Lambda简化代码,强调了内部遍历器的优势,以及如何利用方法引用和函数式接口如Predicate和Function提升代码的可读性和效率。
摘要由CSDN通过智能技术生成

Java lambda 以及 Lambda在集合中的使用   java 1.8 
demo示例
List<ServiceClienter>  temp=serviceClienters.stream().filter(t ->t.getPubDate().equals(daySatisticsB.getMonthDate())).collect(Collectors.toList()); //linq查询
 int orderCount=daySatisticsBs.stream().mapToInt(item -> item.getOrderCount()).sum();  //sum


Lambda在集合中的使用

列表的遍历

提起对于集合的遍历,恐怕下面的这种方式已经是一种思维定式了吧:

final List<String> friends = Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");

for(int i = 0; i < friends.size(); i++) {
     
    System.out.println(friends.get(i));
}

但是仔细想想,以上的代码似乎出现了过多的细节,比如循环变量i的出现。在做简单的遍历操作时,循环变量实际上是不必要的,只有在对某个特定位置的元素执行某个特殊操作时,循环变量的使用才有意义。所以,在Java中引入了增强的for循环,在这种循环方式中,循环变量是不必要的:

for(String name : friends) {
     
    System.out.println(name);
}

这种方式,在实现细节上使用的是iterator接口和它的hasNext(),next()方法。

无论使用哪种for循环,它们仍然使用了外部遍历器(External Iterator)。即在for循环中,你总是有办法通过诸如break,continue等方式来控制遍历的过程。

与外部遍历器相对的,是内部遍历器(Internal Iterator)。在Java 8中,Iterable接口被增强了,现在该接口拥有一个forEach方法用来实现内部遍历器。forEach方法会接受一个Consumer接口类型作为参数,该接口是一个函数式接口(Functional Interface),它是内部遍历器的实现方式。关于函数式接口,可以参考上一篇文章。

friends.forEach(new Consumer<String>() {
     
    public void accept(final String name) {
     
        System.out.println(name);
    }
});

很显然,上述代码中使用的匿名类在Java 8中并不是最好的方案,在这种场景下Lambda表达式是更好的选择:

friends.forEach((final String name) -> System.out.println(name));

forEach方法本身是一个高阶函数,因为它接受了一个Lambda表达式作为其参数,而Lambda表达式在本质上则是一个函数。在Lambda表达式的左边,声明了一个String类型的变量name,它代表了集合中的元素。而箭头右边的代码则表达了对于该元素应该执行何种操作。forEach之所以被称为内部遍历器,原因在于一旦它开始执行了,那么遍历操作就不能够被轻易中断。

同时,借助Java编译器的类型推导(Type Inference)特性,Lambda表达式能够被进一步简化如下:

friends.forEach((name) -> System.out.println(name));

此时,编译器能够通过运行时的上下文知道这个name变量的类型是String。

另外,当Lambda表达式左端只接受一个变量的时候,括号也是可以省略的:

friends.forEach(name -> System.out.println(name));

但是用类型推导有一个不好的地方,就是参数不会自动被final修饰。因此,在Lambda表达式右端,是可以对参数进行修改的,然而这种行为是不被倡导的。

上面的代码已经足够简洁了,但是还有更简洁的方法,那就是使用方法引用:

friends.forEach(System.out::println);

使用这种方式甚至不需要写出Lambda表达式的左端参数部分。关于方法引用的详细情况,会在以后进行介绍。

与使用外部遍历不同,使用内部遍历的好处在于:

  • 放弃使用显式的for循环,因其与生俱来的顺序执行的特性会阻碍并行化。换言之,使用内部遍历时,程序的并行程度能够很容易地被提高。
  • 声明式的代码比命令式的代码更简洁,更具有可读性,更优雅。

列表的变换

将一个集合通过某种计算得到另一个集合是一种常用的操作,也是Lambda表达式的用武之地。 比如,以将一个名字集合转换为首字母大写了的名字集合为例。

为了不改变原集合,最“自然”的方式如下:

final List<String> uppercaseNames = n
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值