一、Lambda表达式

1.语法格式

Lambda是匿名函数,可以传递代码。使用“->”操作符,改操作符将lambda分成两部分:

左侧:指定了 Lambda 表达式需要的所有参数

右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能,也就是实现接口方法的代码

// 语法格式一:无参、无返回值  
@Test  
public void test1() {  
    Runnable runable = () -> System.out.println("hello lambda!");  
    runable.run();  
}  
  
// 语法格式二:有一个参、无返回值  
@Test  
public void test2() {  
    Consumer<String> consumer = (args) -> System.out.println("hello!"  
           + args);  
    consumer.accept("lambda");  
}  
  
// 语法格式三:有多个参、有返回值,并且有多条执行语句,用大括号包围  
@Test  
public void test3() {  
   Comparator<Integer> com = (x, y) -> {  
       System.out.println("hello lambda!");  
       return Integer.compare(x, y);  
    };  
    int rs = com.compare(2, 2);  
    System.out.println(rs);  
}  
  
// 语法格式四:右侧如果只有一条执行语句,可以省略大括号和return  
@Test  
public void test4() {  
   Comparator<Integer> com = (Integer x, Integer y) -> Integer.compare(x, y);  
   int rs = com.compare(2, 2);  
   System.out.println(rs);  
}  

注:lambd可以省略接口参数类型,java编译器会根据上下文进行类型推断

2.函数式接口

(1)只包含一个抽象方法的接口,称为函数式接口,可以在任意函数式接口上使用 @FunctionalInterface 注解,lambda需要函数式接口的支持。

(2)java8内置四大核心函数式接口:

Consumer<T>消费型接口:void accept(T t)

@Test  
public void test2() {  
    Consumer<String> consumer = (args) -> System.out.println("hello!"  
           + args);  
    consumer.accept("lambda");  
}  

Supplier<T>供给型接口:T get()

@Test
public void test5() {
List<Integer> rs=getNumList(6,() -> (int)(Math.random()*100));
System.out.println(rs);
} public List<Integer> getNumList(int size,Supplier<Integer> sup){
List<Integer> list=new ArrayList<Integer>();
for (int i = 0; i < size; i++) {
Integer e=sup.get();
list.add(e);
}
return list;
}

Function<T, R>函数型接口:R apply(T t)

@Test  
public void test6() {  
Function<String, Integer> fun=(str)->str.length();  
int len=fun.apply("lambda");  
System.out.println(len);  
}  

Predicate<T>断定型接口:boolean test(T t)

@Test  
public void test7() {  
Predicate<String> check=(str)->str.equals("lambda");  
boolean rs=check.test("lambda");  
System.out.println(rs);  
}  

3.方法引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!( lambda要实现抽象方法的参数列表,必须与方法引用的方法参数列表保持一致! )。
方法引用:使用操作符 “ ::” 将对象或类和方法的名字分隔开来。

三种主要使用情况:

对象::方法名

PrintStream ps=System.out;  
Consumer<String> consumer =  ps::println;  
consumer.accept("lambda");

类::静态方法名

Comparator<Integer> com = Integer::compare;  
int rs = com.compare(2, 2);  
System.out.println(rs);  

类::实例方法名(前提条件:lambda参数列表的第一个参数是实例方法的调用者,第二个参数是实例方法的入参)

BiPredicate<String,String> check=(str1,str2)->str1.equals(str2);  
BiPredicate<String,String> check1=String::equals;  

4.构造器引用

与函数式接口相结合,自动与函数式接口中方法兼容(需要调用的构造器方法参数列表要与函数式接口中方法的参数列表一致)

格式: ClassName::new

5.数组引用

格式: type[] :: new

二、Stream API

1.说明解释

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。流(Stream)是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算! ”

注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

2.Stream 操作步骤

(1)创建Stream

①可以通过Collection系列集合提供的stream()或者parallelStream()获得

List<String> list=new ArrayList<String>();  
Stream<String> stream=list.stream();  

②可以通过Arrays的静态方法stream()获得数组流

Person[] ps=new Person[10];  
Stream<Person> stream=Arrays.stream(ps); 

③可以通过Stream的静态of()

Stream<String> steam=Stream.of("aa","bb","cc"); 

④可以使用静态方法 Stream.iterate() 和Stream.generate(), 创建无限流

(2)中间条件操作

说明:多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

①筛选与切片
        filter——接收 Lambda , 从流中排除某些元素。
        limit——截断流,使其元素不超过给定数量。
        skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
        distinct——筛选去重,通过流所生成元素的 hashCode() 和 equals() 去除重复元素

List<Person> personList = Arrays.asList(  
                new Person("李四", 20, 10),  
                new Person("张三", 40,30),  
                new Person("王五", 28, 15),  
                new Person("赵六", 60, 60),  
                new Person("赵六", 60, 60),  
                new Person("赵六", 60, 60),  
                new Person("田七", 8,2)  
        );  
          
        Stream<Person> stream=personList.stream();          
        stream.filter((p)->p.getAge()>20)//过滤保留age>20  
        .limit(5)//只取前两个  
        .skip(1)//跳过前一个,返回剩下的  
        .distinct()//去重,自动定义对象去重要重写equals和hashcode  
        .forEach(System.out::println); 

②映射
        map——接收 Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
        flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

Stream<Person> stream=personList.stream();          
stream.map((p)->p.getName())//提取name,组成新的Stream流  
     .forEach(System.out::println);  

③排序
        sorted()——自然排序(Comparable)
        sorted(Comparator com)——定制排序

(3)执行操作

查找与匹配
        allMatch——检查是否匹配所有元素,返回boolean
        anyMatch——检查是否至少匹配一个元素,返回boolean
        noneMatch——检查是否没有匹配的元素,返回boolean
        findFirst——返回第一个元素
        findAny——返回当前流中的任意一个元素
        count——返回流中元素的总个数
        max——返回流中最大值
        min——返回流中最小值

 

  

  

 

java8中Lambda表达式和Stream API的更多相关文章

  1. 十分钟学会Java8:lambda表达式和Stream API

    Java8 的新特性:Lambda表达式.强大的 Stream API.全新时间日期 API.ConcurrentHashMap.MetaSpace.总得来说,Java8 的新特性使 Java 的运行 ...

  2. 十分钟学会Java8的lambda表达式和Stream API

    01:前言一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏 ...

  3. Java8的lambda表达式和Stream API

    一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏味,非过来 ...

  4. Java8中Lambda表达式的10个例子

    Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...

  5. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

  6. JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用

    jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default   Lambda表达式     L ...

  7. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

  8. 公子奇带你一步一步了解Java8中Lambda表达式

    在上一篇<公子奇带你一步一步了解Java8中行为参数化>中,我们演示到最后将匿名实现简写为 (Police police) -> "浙江".equals(poli ...

  9. JDK1.8中的Lambda表达式和Stream

    1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...

随机推荐

  1. 程序员周末阿里面试,5分钟就被一道题秒杀:HashMap与Hashtable

    你们可能会想,我这么菜的吗?5分钟都坚持不了? 本文说起来会有点尴尬,毕竟这是我曾经经历过的故事 那时候的我还真菜,每天写着 if/ for 及一些简单的业务逻辑代码,虽工作有些日子了,但技术水平还停 ...

  2. 配置babel

    配置babel ECMAScript的版本,每年都会定期举行会议,发布各种标准,当前版本到了2019,但大部分人使用的浏览器,都可以支持es2015,也就是es6,要等到大部分浏览器都支持到最新版本, ...

  3. MySQL:windows中困扰着我们的中文乱码问题

    前言:什么是mysql中的中文乱码问题? 话不多说,直接上图 这个东西困扰了我好久,导致我现在对windows映像非常不好,所以就想改成Linux,行了,牢骚就发到这里,直接说问题,明眼人一眼就看出来 ...

  4. RabbitMQ系列(五)使用Docker部署RabbitMQ集群

    概述 本文重点介绍的Docker的使用,以及如何部署RabbitMQ集群,最基础的Docker安装,本文不做过多的描述,读者可以自行度娘. Windows10上Docker的安装 因为本人用的是Win ...

  5. SQL Server 2008 R2 下如何清理数据库日志文件

    废话不多说,直接上代码,清理后日志文件为1M USE [master] GO ALTER DATABASE [数据库名] SET RECOVERY SIMPLE WITH NO_WAIT GO ALT ...

  6. .Net Core实现记录接口执行时间的中间件

    项目中有时接口访问时间过长,但是通过浏览器F12查看时,接口访问时间很正常,所以就很奇怪,于是写一个中间件,记录所有接口访问时间的中间件. 一.中间件 中间件是应用程序处理管道中的组件,用来处理请求和 ...

  7. vue开发中,build时css打包报错

    vue在打包的时候css报错,首先声明的这个并没有解决webpack本身的问题,本来这个也是一个警示,不会影响代码正常运行 这个是因为我在多个页面引入了同一个css文件,webpack打包时候对css ...

  8. [Redux] redux的概述

    redux 的概述 随着 javascript 单页应用的不断发展,javascript 需要管理比以往都要多的状态,管理不断变化的 state 非常困难,数据流动不断变的模糊不可预测,代码的开发与维 ...

  9. 南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题

    问题 A: 割点与桥 时间限制: 1 Sec  内存限制: 5 MB提交: 475  解决: 34提交 状态 算法问答 题目描述 给出一个无向连通图,找到所有的割点和桥 输入 第一行:点的个数,如果点 ...

  10. c# chart控件柱状图,改变柱子宽度

    让柱状图紧挨 改变柱状图宽度 chart1.Series[0]["PointWidth"] = "2";