标签分类
技术文章
当前位置:主页 > 计算机编程 > java > Java8中Lambda表达式使用和Stream API详解

Java8中Lambda表达式使用和Stream API知识点详解

  • 发布时间:
  • 作者:码农之家原创
  • 点击:195

Java8中Lambda表达式使用和Stream API详解

这篇文章主要知识点是关于lambda,stream,java8,lambda表达式,java8,stream,api,Java8中Lambda表达式使用和Stream API详解,Java8与Scala中的Lambda表达式深入讲解 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

精通Java并发编程
  • 类型:Java大小:200.7 MB格式:PDF出版:人民邮电出版社作者:哈维尔
立即下载

前言

Java8 的新特性:Lambda表达式、强大的 Stream API、全新时间日期 API、ConcurrentHashMap、MetaSpace。总得来说,Java8 的新特性使 Java 的运行速度更快、代码更少、便于并行、最大化减少空指针异常。

0x00. 前置数据

private List<People> peoples = null;

@BeforeEach void before () {
  peoples = new ArrayList<>();
  peoples.add(new People("K.O1", 21, new Date()));
  peoples.add(new People("K.O3", 23, new Date()));
  peoples.add(new People("K.O4", 24, new Date()));
  peoples.add(new People("K.O5", 25, new Date()));
  peoples.add(new People("K.O2", 22, new Date()));
  peoples.add(new People("K.O6", 26, new Date()));
}

0x01. 提取对象中的一列

/**
* 提取1列
*/
@Test void whenExtractColumnSuccess () {
  //第一种写法
  List<Integer> ages1 = peoples.stream().map(people -> people.getAge()).collect(Collectors.toList());
  System.out.println("###println: args1----");
  ages1.forEach(System.out::println);

  //简单一点的写法
  List<Integer> ages2 = peoples.stream().map(People::getAge).collect(Collectors.toList());
  System.out.println("###println: args2----");
  ages1.forEach(System.out::println);
}

###println: args1----
21
22
23
24
25
26
###println: args2----
21
22
23
24
25
26

/**
  * 只要年纪大于25岁的人
  */
@Test void whenFilterAgeGT25Success () {
  List<People> peoples1 = peoples.stream().filter(x -> x.getAge() > 25).collect(Collectors.toList());
  peoples1.forEach(x -> System.out.println(x.toString()));
}

People{name='K.O6', age=26, birthday=Wed May 15 22:20:22 CST 2019}

0x03. 列表中对象数值型列数据求和

/**
  * 求和全部年纪
  */
@Test void sumAllPeopleAgeSuccess () {
  Integer sum1 = peoples.stream().collect(Collectors.summingInt(People::getAge));
  System.out.println("###sum1: " + sum1);
  Integer sum2 = peoples.stream().mapToInt(People::getAge).sum();
  System.out.println("###sum2: " + sum2);
}

    ###sum1: 141
    ###sum2: 141

0x04. 取出集合符合条件的第一个元素

/**
  * 取出年纪为25岁的人
  */
@Test void extractAgeEQ25Success () {
  Optional<People> optionalPeople = peoples.stream().filter(x -> x.getAge() == 25).findFirst();
  if (optionalPeople.isPresent()) System.out.println("###name1: " + optionalPeople.get().getName());

  //简写
  peoples.stream().filter(x -> x.getAge() == 25).findFirst().ifPresent(x -> System.out.println("###name2: " + x.getName()));
}

###name1: K.O5
###name2: K.O5

0x05. 对集合中对象字符列按规则拼接

/**
  * 逗号拼接全部名字
  */
@Test void printAllNameSuccess () {
  String names = peoples.stream().map(People::getName).collect(Collectors.joining(","));
  System.out.println(names);
}

K.O1,K.O2,K.O3,K.O4,K.O5,K.O6

0x06. 将集合元素提取,转为Map

/**
  * 将集合转成(name, age) 的map
  */
@Test void list2MapSuccess () {
  Map<String, Integer> map1 = peoples.stream().collect(Collectors.toMap(People::getName, People::getAge));
  map1.forEach((k, v) -> System.out.println(k + ":" + v));

  System.out.println("--------");

  //(name object)
  Map<String, People> map2 = peoples.stream().collect(Collectors.toMap(People::getName, People::getThis));
  map2.forEach((k, v) -> System.out.println(k + ":" + v.toString()));
}

//People中自己实现的方法
public People getThis () {
  return this;
}

K.O2:22
K.O3:23
K.O1:21
K.O6:26
K.O4:24
K.O5:25
--------
K.O2:People{name='K.O2', age=22, birthday=Wed May 15 22:42:39 CST 2019}
K.O3:People{name='K.O3', age=23, birthday=Wed May 15 22:42:39 CST 2019}
K.O1:People{name='K.O1', age=21, birthday=Wed May 15 22:42:39 CST 2019}
K.O6:People{name='K.O6', age=26, birthday=Wed May 15 22:42:39 CST 2019}
K.O4:People{name='K.O4', age=24, birthday=Wed May 15 22:42:39 CST 2019}
K.O5:People{name='K.O5', age=25, birthday=Wed May 15 22:42:39 CST 2019}

0x07. 按集合某一属性进行分组

/**
  * 按名字分组
  */
@Test void listGroupByNameSuccess() {
  //添加一个元素方便看效果
  peoples.add(new People("K.O1", 29, new Date()));
  Map<String, List<People>> map = peoples.stream().collect(Collectors.groupingBy(People::getName));

  map.forEach((k, v) -> System.out.println(k + ":" + v.size()));
}

K.O2:1
K.O3:1
K.O1:2
K.O6:1
K.O4:1
K.O5:1

0x08. 求集合对象数值列平均数

/**
  * 求人平均年龄
  */
@Test void averagingAgeSuccess () {
  Double avgAge = peoples.stream().collect(Collectors.averagingInt(People::getAge));
  System.out.println(avgAge);
}

23.5

0x09. 对集合按某一列排序

/**
  * 按年龄排序
  */
@Test void sortByAgeSuccess () {
  System.out.println("###排序前---");
  peoples.forEach(x -> System.out.println(x.getAge()));

  peoples.sort((x, y) -> {
    if (x.getAge() > y.getAge()) {
      return 1;
    } else if (x.getAge() == y.getAge()) {
      return 0;
    }
    return -1;
  });

  System.out.println("###排序后---");
  peoples.forEach(x -> System.out.println(x.getAge()));
}

###排序前---
21
23
24
25
22
26
###排序后---
21
22
23
24
25
26

未完待续

<源码地址:https://github.com/cos2a/learning-repo/tree/master/core-java8>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对码农之家的支持。

Java8与Scala中的Lambda表达式深入讲解

前言

最近几年Lambda表达式风靡于编程界。很多现代编程语言都把它作为函数式编程的基本组成部分。基于JVM的编程语言如Scala、Groovy及Clojure把它作为关键部分集成在语言中。而如今,(最终)Java 8也加入了这个有趣的行列。

Java8 终于要支持Lambda表达式!自2009年以来Lambda表达式已经在Lambda项目中被支持。在那时候,Lambda表达式仍被称为Java闭包。在我们进入一些代码示例以前,先来解释下为什么Lambda表达式在Java程序员中广受欢迎。

1、为什么使用Lambda表达式

Lambda表达式通常使用在图形用户界面(GUI)的开发中。一般来说,GUI编程将程序行为和事件做连接。比如,当用户按下一个按钮(触发一个事件),你的程序就需要去执行某些行为,可能是将一些数据储存到一个数据存储器中。在Swing中,可以使用ActionListener来实现:

class ButtonHandler implements ActionListener {
 public void actionPerformed(ActionEvent e) {
 //do something
 }
}

class UIBuilder {
 public UIBuilder() {
 button.addActionListener(new ButtonHandler());
 }
}

这个例子表明了 ButtonHandler 类作为一个回调替换的用法。在这里 ButtonHandler 类仅包含 ActionListener 接口定义的 actionPerformed 方法。我们可以使用匿名内部类来简化代码:

class UIBuilder {
 public UIBuilder() {
 button.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent event) {
 //do something
 }
 })
 }
}

这样代码简洁多了。更仔细的去看代码时,就会发现我们还创建一个只生成一个实例的类,而这个实例也仅仅持有一个独立的方法。这恰好是Lambda表达式所能解决的其中一类问题。

2、Lambda表达式代替函数

一个lambda表达式从字面上讲就是一个函数。它定义了一个函数的输入参数和函数体。Java 8 中的,lambda表达式语法尚未确定,不过大致应该类似这个样子的:

(type parameter) -> function_body

一个具体的例子:

(String s1, String s2) -> s1.length() - s2.length();

这个lambda表达式用来计算两个字符串的长度差。还有一些扩展的语法,比如避免参数的类型定义(我们马上见看到例子)还有使用{和}来支持多行定义。

Collections.sort() 方法是lambda表达的理想例子。它允许我们将字符串按照长度排序:

List<String> list = Array.asList("loooooong", "short", "tiny");
Collections.sort(list, (String s1, String s2) -> s1.length() - s2.length());
> "tiny", "short", "loooooong".

所以,不像现在java必须要求的向sort方法输入一个已经实现的Comparator(比较器)而是传送一个lambda表达式我们就可以得到相同的结果。

3、Lambda表达式代替闭包

lambda表达式有许多有趣的特性。其中之一是,它们是闭包。一个闭包允许函数访问直接词法作用域之外的变量。

String outer = "java 8"
(String s1) -> s1.length() - outer.length()

在例子中,lambda表达式访问了字符串 outer 这个作用域之外定义的变量。对于内联闭包来说这是很难做到的。

4、Lambda表达式也支持类型推论

类型推论是java 7 引入的但它同样适用于lambda表达式。简单来说,类型推论意味着程序员可以在任意一个编译器能够自动推断出类型的地方省略类型定义。

如果类型推论能够应用到前面的排序lambda表达式上,那么它就能写成下面的样子:

List<String> list = Arrays.asList(...);
Collections.sort(list, (s1, s2) -> s1.length()-s2.length());

就像你所见到的一样,参数s1和s2的类型被省略了。因为编译器知道list是一个字符串集合,它知道被用来作为比较器的lambda表达式必定是相同的类型。因此,这个类型不需要显式地声明,即使你有这么做的自由。

类型推论的主要优势就是减少样板代码,如果编译器可以为我们识别类型,为什么我们必须自己定义它们。

5、珍爱Lambda表达式,远离匿名内部类

我们来体会下,为何lambda表达式和类型推论有助于简化我们前面所提到的回调例子:

class UIBuilder {
 public UIBuilder() {
 button.addActionListener(e -> //process ActionEvent e)
 }
}

我们下载直接传送一个lambda表达式进入 addActionListener 方法来代替前面定义的持有回调方法的类。除了减少模板代码和提高可读性以外,它使我们直接表达我们唯一感兴趣的事情:处理事件。

在我们了解lambda表达式更多优势之前,先来看看在Scala中的lambda表达式副本。

6、Scala中的Lambda表达式

在函数式编程中,函数是基本的构造块。Scala融合了java中的面向对象编程和函数式编程。在Scala中,一个lambda表达式是种叫做“函数”或者“函数文本”。Scala中的函数属于一等公民。它们可以被分配给vals或者vars(最终变量或者非最终变量),它们可以作为其他函数的参数,也可以组合成新的函数。

在Scala中一个函数文本写成如下形式:

(argument) => //funtion body

举例来说,前面提到的java 用来计算两个字符串长度差的 lambda 表达式,在Scala中写作如下:

(s1: String, s2 :String) => s1.length - s2.length

Scala中的函数文本也是闭包。它可以访问在直接词法作用域之外定义的变量。

val outer =10
val myFuncLiteral = (y: Int) => y * outer
val result = myFuncLiteral(2)
> 20

这个例子结果是20.

正如你所见,我们将函数文本分配给了变量 myFuncLiteral。

java 8 的lambda表达式和Scala的函数文本在语法和语义上的相似性是十分明显的。从语义上讲它们是相同的,而语法上的唯一不同就是箭头符号(java8 ->, scala =>)和我们没有提到的简化符号。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对码农之家的支持。

以上就是本次给大家分享的全部知识点内容总结,大家还可以在下方相关文章里找到vue项目中使用md5加密以及、 spring+springmvc+mybatis整合注、 详解vue axios封装请求状态、 等java文章进一步学习,感谢大家的阅读和支持。

上一篇:java对synchronized的优化知识点总结

下一篇:java写一个锁Lock的步骤方法

展开 +

收起 -

学习笔记
网友NO.462658

详解Java中的Lambda表达式

简介 Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。 Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。 Lambda来源于希腊字母入,发音为 /'lmd┉/ 对高数有所了解的人都知道λ用于声明一个数学逻辑系统,表示根据XX的输入参数,会返回某个Y结果。这正是编程语言中函数(方法)的意思。 因此Lambda表达式在编程语言中说白了就是指的一个方法表达式。 为什么要搞出这么一个东西来呢?这是由于我们的编程语言都是按照面向对象设计的,也就是我给你提供几个对象,你给我返回几个对象,但是有时候我们仅仅是把一些算法逻辑传来传去。并不需要一个对象这么完整的结构。 OO语言常用的写法就是把这段算法逻辑作为对象中的某个方法,然后再把这个对象传来传去。这样做固然没问题,但是却对开发人员并不友好,由于大量的冗余代码,导致阅读起来……

网友NO.401190

java中Lambda常用场景代码实例

本文实例为大家分享了java中Lambda常用场景的具体代码,供大家参考,具体内容如下 public class test18 { /** * lambda表达式的常用场景 */ @Test public void test() { ListString list_one = new ArrayList(); list_one.add("NIKE"); list_one.add("Addidas"); /** * 用在匿名内部类里简写 ()- */ new Thread(new Runnable() { @Override public void run() { System.out.println("do nothing"); } }).start(); new Thread(() - System.out.println("do nothing")).start(); //用在集合比较器里 Collections.sort(list_one, new ComparatorString() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); Collections.sort(list_one, (o1, o2) - o1.compareTo(o2));//正序 Collections.sort(list_one, (o1, o2) - -o1.compareTo(o2));//逆序 //用在遍历集合 或操作集合中元素的时候 list_one.forEach(System.out::println); List result = new ArrayList(); list_one.stream().forEach(item - result.add(item)); System.out.println("--boundary--"); //通过自定义filter方法 或者 集合.stream().filter(Predicate) filter(list_one, n - n.startsWith("N")); filter(list_one, n - true); filter(list_one, n - false); filter(list_one, n - n.length() 5); PredicateString predicate = n - n.startsWith("N"); list_one.stream().filter(predicate).forEach(System.out::print); ListInteger list3 = new ArrayList(); list3.add(10); list3.add(8); list3.add(3); list3.add(15); list3.add(20); PredicateInteger predicate1 = n - Integer.valueOf(n) 10; //用于map ……

网友NO.814550

java使用lambda表达式对List集合进行操作技巧(JDK1.8)

具体代码如下所示: import java.util.ArrayList;import java.util.List;import java.util.function.Predicate;import java.util.stream.Collectors;public class LambdaStudy{ public static void main(String[] args) { //初始化list集合 ListString list = new ArrayListString(); list.add("测试数据1"); list.add("测试数据2"); list.add("测试数据3"); list.add("测试数据12"); //使用λ表达式遍历集合 list.forEach(s - System.out.println(s)); //结合Predicate使用和过滤条件筛选元素 PredicateString contain1 = n - n.contains("1"); PredicateString contain2 = n - n.contains("2"); //根据条件遍历集合 list.stream().filter(contain1).forEach(n - System.out.println(n)); list.stream().filter(s - contain1.test(s)).forEach(s - System.out.println(s)); list.stream().filter(contain1.and(contain2)).forEach(n - System.out.println(n)); list.stream().filter(contain1.or(contain2)).forEach(n - System.out.println(n)); //将过滤后的元素重新放到一个集合中 ListString newList = list.stream().filter(contain1.and(contain2)).collect(Collectors.toList()); newList.forEach(s - System.out.println(s)); }} 总结 以上所述是小编给大家介绍的java使用lambda表达式对List集合进行操作技巧(JDK1.8),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对码农之家网站的支持! ……

<
1
>

Copyright 2018-2019 xz577.com 码农之家

版权责任说明