1.java8中Lambda表达式基础语法:

(x,y) -> {}

左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型;

中间是一个jdk8新定义的箭头符号;

右侧是一个大括号,在括号内编写抽象方法的实现内容,有参时,可直接使用左侧括号中的对应参数,与正常方法的方法体相同;

使用方式:实现只有一个抽象方法的接口时会自行匹配到该方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码(代码实现为单行时可去掉大括号{})

示例:

     @Test
public void test() {
//输入一个数,与100比较大小 //实现方式1 匿名内部类:
Comparable<Integer> comparable1 = new Comparable<Integer>() {
@Override
public int compareTo(Integer o) {
return Integer.compare(o, 100);
}
};
comparable1.compareTo(2); //实现方式2 Lambda表达式:实现只有一个抽象方法的Comparable接口时会自行匹配到compareTo方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码
Comparable<Integer> comparable2 = (x) -> Integer.compare(x, 100);
comparable2.compareTo(2);
}

2.Lambda表达式的函数式编程需要函数式接口(有且只有一个抽象方法的接口)的支持,为了防止使用Lambda表达式时都必须手动添加接口,Java8内置了四大核心函数式接口:

/**
* Java8内置的四大核心函数式接口
*
* Consumer<T> :消费型接口
* void acept(T t);
*
* Supplier<T> :供给型接口
* T get();
*
* Function<T,R> :函数型接口
* R apply(T t);
*
* Predicate<T> :断言型接口
* boolean test(T t);
*/
     public static void main(String[] args) {
//内置函数式接口使用示例 //消费型接口Consumer,输入一个参数,对其进行打印输出
Consumer<String> consumer = (x) -> System.out.println(x);
//打印字符串
consumer.accept("hehe"); //供给型接口Supplier,返回指定字符串
Supplier<String> supplier = () -> "Hello world!";
//获取字符串
supplier.get(); //函数型接口Function,输入字符串,返回字符串长度
Function<String, Integer> function = (x) -> x.length();
//获取字符串长度
function.apply("Hello world!"); //断言型接口Predicate,输入数字,判断是否大于0
Predicate<Integer> predicate = (x) -> x > 0;
//获取判断结果
predicate.test(10);
}

除了这四个接口外还有其他多参数的子接口,自行查找。


3.某些情况下要实现的业务部分已有方法实现,可直接引用该方法,此时可使用Lambda表达式中的方法引用: /**
* 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”
* 可以理解为方法引用是lambda表达式的另外一种表达形式
*
* 主要有三种语法格式:
*
* 对象::实例方法名
*
* 类::静态方法名
*
* 类::实例方法名
*/
方法引用注意点:被引用的方法的参数和返回值必须和要实现的抽象方法
的参数和返回值一致
         //引用out对象的打印输出方法作为Consumer接口accept方法的具体实现
Consumer<String> consumer1 = System.out::println;
consumer1.accept("hehe"); //lambda表达式常用方式
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
//方法引用:类::实例方法(方法传入参数是两个参数,且第一个参数作为方法调用对象,第二个参数作为调用的方法的参数)
BiPredicate<String, String> bp2 = String::equals;

 4.构造器引用:通过函数式接口实例化类时可进行构造器引用

注意点:引用到的是与函数式接口中的方法参数个数及类型相同的构造器

         //lambda表达式常用方式
Supplier<Passenger> supplier1 = () -> new Passenger();
//构造器引用:通过类型推断,引用无参构造器
Supplier<Passenger> supplier2 = Passenger::new;
      
//lambda表达式常用方式
BiFunction<String, String, Passenger> function1 = (x, y) -> new Passenger(x, y);
//构造器引用:通过类型推断,引用有两个String参数的构造器
BiFunction<String, String, Passenger> function2 = Passenger::new;

5.数组引用:

         //lambda表达式常用方式
Function<Integer, String[]> fun1 = (x) -> new String[x];
String[] strs1 = fun1.apply(10);
//数组引用
Function<Integer, String[]> fun2 = String[]::new;
String[] strs2 = fun2.apply(10);

6.Stream流的应用

Stream的使用步骤:
1 创建Stream对象
2 执行中间操作
3 执行终止操作

1)Stream对象的创建方式:

     /**
* Stream的使用:
* 1 创建Stream对象
* 2 中间操作
* 3 终止操作
*/
public static void main(String[] args) {
//stream对象获取方式:
String[] strings = {"1", "2", "3", "4"}; //方式1:数组获取stream对象
Stream<String> stream1 = Arrays.stream(strings); //方式2:集合获取stream对象
List<String> list = Arrays.asList(strings);
Stream<String> stream2 = list.stream(); //方式3:Stream静态方法of获取stream对象
Stream<String> stream3 = Stream.of(strings); //方式4:创建无限流(seed起始值,重复无限次执行的方法)
//无限流1:迭代
Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
//无限流2:生成
Stream<Double> stream5 = Stream.generate(() -> Math.random());
}

2)Stream常用中间操作方法:

         //Stream常用方法(链式方法,从上往下执行,下一个方法进行处理的对象是上一个方法处理后的结果)
Arrays.stream(new Integer[]{1, 63, 3, 7, 11, 54, 34})
//过滤器,传入一个Predicate断言型接口实现,Stream会进行内部遍历,将保留断言返回true的元素(此处过滤保留值大于4的元素)
.filter(x -> x > 4)
//截断流,只获取前n个元素(此处获取满足过滤器条件的前2个元素)
.limit(5)
//跳过元素,跳过前n个元素,获取后面的元素,若流中的元素不足n个,则返回一个空流,与limit互补(此处取除第一个元素外的元素)
.skip(1)
//映射,对流内元素进行处理,可以是转换类型、获取属性值等等,传入一个Function函数型接口实现(此处对流内元素全部加5)
.map(x -> x + 5)
//自然排序(按照Comparable默认排序,此处为Integer从小到大排序)
.sorted()
//定制排序(按照Comparator自定义排序,此处处理为Integer从大到小排序)
.sorted((x, y) -> -Integer.compare(x, y))
//终止操作,遍历流内元素,传入一个Consumer消费型接口实现(此处简单对流内元素进行打印输出)
.forEach(System.out::println);

3)Stream常用终止操作方法:

         //终止操作
Integer[] integers = {1, 63, 3, 7, 11, 54, 34};
List<Integer> list = Arrays.asList(integers); //匹配所有元素,传入一个Predicate断言型接口实现,当所有元素都满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b1 = list.stream().allMatch(x -> x > 0); //匹配元素,传入一个Predicate断言型接口实现,当有至少一个元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b2 = list.stream().anyMatch(x -> x > 0); //无匹配元素,传入一个Predicate断言型接口实现,没有元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
boolean b3 = list.stream().noneMatch(x -> x > 0); //匹配第一个元素
Optional<Integer> o4 = list.stream().findFirst(); //匹配任意一个元素
Optional<Integer> o5 = list.stream().findAny(); //获取流中元素个数
long l6 = list.stream().count(); //获取流中满足条件的最小值
Optional<Integer> min = list.stream().min(Integer::compare);
System.out.println("min:" + min.get()); //获取流中满足条件的最大值
Optional<Integer> max = list.stream().max(Integer::compare);
System.out.println("max:" + max.get()); //归约(将identity作为起始x,第一个元素作为y,计算结果再作为x与下一个元素进行计算,得出计算结果)
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
//归约(未设置起始x,因此有可能空指针,因此返回类型为Optional)
Optional<Integer> reduce1 = list.stream().reduce(Integer::sum); //收集(将流转换为其他形式,接受一个Collector接口实现,用于给Stream中元素做汇总的方法)
List<Integer> collect = list.stream().collect(Collectors.toList());
//转为hashset
HashSet<Integer> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new));
//取平均值
Double collect2 = list.stream().collect(Collectors.averagingInt((x) -> x));
System.out.println("avg:" + collect2);
//求和
Double collect3 = list.stream().collect(Collectors.summingDouble(x -> x));
System.out.println("sum:" + collect3);
待续。。。

JDK8 新特性 Lambda表达式的更多相关文章

  1. 大数据之路week06--day03(jdk8新特性 Lambda表达式)

    为什么使用Lambda表达式?(做为初学者接触这个新的语法,会很懵逼,说道理,我在接触到这一块的时候,语法规则我看到了也很懵逼,因为这个和逻辑的关系不是很大,但就是作为一种新的语法出现,一时间很难接受 ...

  2. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  3. Java8新特性-Lambda表达式是什么?

    目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...

  4. Java 8 新特性 - Lambda表达式

    Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...

  5. C#10新特性-lambda 表达式和方法组的改进

    C# 10 中对Lambda的语法和类型进行了多项改进: 1. Lambda自然类型 Lambda 表达式现在有时具有"自然"类型. 这意味着编译器通常可以推断出 lambda 表 ...

  6. jdk8的新特性 Lambda表达式

    很多同学一开始接触Java8可能对Java8 Lambda表达式有点陌生. //这是一个普通的集合 List<Employee> list = em.selectEmployeeByLog ...

  7. JDK8的新特性——Lambda表达式

    JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运用,甚至不被开发者所熟知. ...

  8. Java8新特性: lambda 表达式介绍

    一.lambda 表达式介绍 lambda 表达式是 Java 8 的一个新特性,可以取代大部分的匿名内部类,简化了匿名委托的使用,让你让代码更加简洁,优雅. 比较官方的定义是这样的: lambda ...

  9. java8新特性——Lambda表达式

    上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...

随机推荐

  1. (十一)springmvc和spring的整合

    1:Maven引入相关的jar包. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  2. C++虚函数【Java有虚函数吗?】

    1,简单介绍 定义在基类中的函数,子类必须对其进行覆写![必须对其进行覆写?!]——Java中的接口.Abstract方法中的抽象类也有这样的要求. C++中定义: virtual void deal ...

  3. oracle查询十分钟之前的数据

    select * from TABLE as of timestamp sysdate - 10/1440 t WHERE ColName='1111'; TABLE:表名 WHERE:查询子句 sy ...

  4. vue中子组件的created、mounted钩子中获取不到props中的值问题

    父子组件通信 这个官网很清楚,也很简单,父组件中使用v-bind绑定传送,子组件使用props接收即可 例如: 父组件中: <template> <div> <head- ...

  5. css 关于"浮动边距加倍"及其解决方法-------解决方案是在这个div里面加上display:inline;

    写div代码的时候,经常发现明明宽度算得很准确,但是莫明其妙的会和计划的布局不太一样- -|||开始以为自己代码写的有问题,拼命找bug也一无所获,最后可能会稍微修改样式来达到想要的效果,但终究也是外 ...

  6. JavaScript--Function对象(函数)的声明和作用域

    Funtion 封装了可重复使用的代码块对象,函数名是一个引用函数对象的变量 声明提前:在程序开始执行之前,将var 变量和function函数提前声明 但赋值并不会提前 它的三种创建方法: 创建1 ...

  7. css的导入与基础选择器

    css是什么 css也是一门标记语言,主要用作修改控制html的样式 css书写的位置(导入) css是用来控制页面标签的样式,但是可以根据实际情况书写在不同的位置, 放在不同位置有不同的专业叫法,可 ...

  8. JoinableQueue类与线程

    生产者消费者的问题及其解决办法 问题 在之前的生产者消费者模型中,生产者和消费者只有一个, 那么生产者往队列里put几次,消费者就get几次,但是存在一个问题, 生产者不一定只有一个,消费者也不一定只 ...

  9. nc 命令

    目录 nc 命令 一.简介 二.案例 1.端口扫描 2.聊天 3.文件传输 4.目录传输 5.加密网络发送的数据 6.流视频 7.克隆一个设备 8.打开一个shell 9.反向shell 10.指定端 ...

  10. 网络分类及OSI七层模型

    一.网络分类: 局域网(LAN)是指在某一区域内由多台计算机互联成的计算机组.一般是方圆几千米以内.局域网可以实现文件管理.应用软件共享.打印机共享.工作组内的日程安排.电子邮件和传真通信服务等功能. ...