1.lambda表达式

格式:(参数) -> {代码段}

如:new Thread(() -> {System.out.println("hello world!")}).start(); 这就是lambda表达式。

lambda的实现需要依赖函数式接口,lambda本质上是匿名内部类,jdk1.8以前,如果方法内需要操作其他接口的实现方法,可以通过匿名内部类来实现,

jdk1.8之后可以通过lambda表达式来代替匿名内部类,并且更为简化。

package java8;public class LambdaDemo {public static void main(String[] args) {//JDK1.8之前使用接口,采用匿名内部类的方式MyInterface mi = new MyInterface() {@Overridepublic void test() {System.out.println("test");}};mi.test();//JDK1.8之后,使用lambda表达式MyInterface lmi = () -> {System.out.println("test");};lmi.test();}
}
//定义一个函数式接口,只有一个抽象方法
interface MyInterface{void test();
}

函数式接口 : 有且只有一个的抽象方法的接口称为函数式接口

函数式接口的常用接口 Function, Predicate,Supplier,Consumer 都在java.util.function包下

Function接口:R apply(T t) 接收一个参数并返回一个对象

package java8;import java.util.function.Function;public class LambdaDemo {public static void main(String[] args) {// function的使用// 传统模式,第一个泛型:接收的参数类型 第二个泛型,返回的参数类型Function<String, String> function1 = new Function<String, String>() {@Overridepublic String apply(String t) {return t;}};// 调用apply方法,并获取返回结果String res1 = function1.apply("function的使用");System.out.println(res1);// lambda的使用,当参数只有一个且不写参数类型时,"()"可以省略Function<String, String> function2 = t -> {return t;};// 调用apply方法,并获取返回结果String res2 = function2.apply("function的使用");System.out.println(res2);}
}

Predicate接口 : boolean test(T  t) 接收一个参数,返回一个boolean值

常用来比较

package java8;import java.util.function.*;public class LambdaDemo {public static void main(String[] args) {// predicate的使用// 传统模式,泛型参数:接收的参数类型Predicate<Integer> predicate1 = new Predicate<Integer>() {@Overridepublic boolean test(Integer t) {// 大于等于10就为真,否则为假return t >= 10;}};// 执行predicate1的方法System.out.println(predicate1.test(11));System.out.println(predicate1.test(8));//使用lambda表达式Predicate<Integer> predicate2 = new Predicate<Integer>() {@Overridepublic boolean test(Integer t) {// 大于等于10就为真,否则为假return t >= 10;}};// 执行predicate1的方法System.out.println(predicate2.test(11));System.out.println(predicate2.test(8));}
}

Supplier接口 :T get() 返回一个对象

生产者消费者模式的生产者,只管生产对象

package java8;import java.util.function.*;public class LambdaDemo {public static void main(String[] args) {//Supplier的使用// 传统模式,泛型参数:返回的参数类型Supplier<String> s1 = new Supplier<String>() {@Overridepublic String get() {return new String("supplier");}};//调用System.out.println(s1.get());// 使用lambda表达式//当代码只有一句时,可以省略"{}",不接收参数时,"()"不能省略Supplier<String> s2 = () -> new String("supplier");System.out.println(s2.get());}
}

Consumer接口 :  accept(T t)接收一个参数,不返回任何值

生产者消费者模式的生产者,只管消费对象

package java8;import java.util.function.*;public class LambdaDemo {public static void main(String[] args) {// Consumer的使用// 传统模式,泛型参数:返回的参数类型Consumer<String> con1 = new Consumer<String>() {@Overridepublic void accept(String t) {System.out.println(t);}};con1.accept("consumer");//使用lambda表达式,同时省略"()","{}"Consumer<String> con2 = t -> System.out.println(t);con2.accept("consumer");}
}

lambda实战用法:

package java8;import java.util.function.*;public class LambdaDemo {public static void main(String[] args) {//Runnable的实现,new Thread(() -> {System.out.println(Thread.currentThread().getName() + " run");}).start();System.out.println(Thread.currentThread().getName() + " run");}
}

方法引用:

方法引用是指lambda表达式中只有一句方法调用,而这个方法有真实存在,此时就可以用方法引用来替换lambda表达式。

方法引用有四种类型

类名::静态方法名

对象名::实例方法名

类名::实例方法名

类名::new

package java8;import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Supplier;public class MethodReferenceDemo {public static void main(String[] args) {// 定义3个Student对象Student s1 = new Student("zhangsan", 90);Student s2 = new Student("lisi", 60);Student s3 = new Student("wangwu", 70);// 添加到集合List<Student> students = Arrays.asList(s1, s2, s3);//普通的lambda实现// sort接收两个参数,第一个参数,要排序的集合,第二个参数,Comparator接口的实现// Collections.sort(students, (stu1,stu2) -> StudentSortUtil.sortByScore(stu1,stu2));// students.forEach(t -> System.out.println(t.getScore()));// 方法引用1---类名::静态方法名// Collections.sort(students, StudentSortUtil::sortByScore);// students.forEach(t -> System.out.println(t.getScore()));//创建实例对象,调用实例对象的方法StudentSortUtil ssu = new StudentSortUtil();//普通的lambda实现
//      Collections.sort(students, (stu1, stu2) -> ssu.sortByScoreInstance(stu1, stu2));
//      students.forEach(t -> System.out.println(t.getScore()));// 方法引用2---对象名::实例方法名
//      Collections.sort(students, ssu::sortByScoreInstance);
//      students.forEach(t -> System.out.println(t.getScore()));/** 方法引用3---类名::实例方法名* Student的sortByScore()只有一个参数,而Comparator的实现需要两个参数,为什么编译器不报错?* 这是因为sortByScore是一个普通方法,要使用这个方法肯定要有一个Student类的实例对象来调用* 而调用的这个方法的对象就作为Comparator的第一个参数对象传递进来* 例String的compareTo()方法,调用这个方法首先要有一个String的实例对象,* 此处str就是这个实例对象,str就作为Comparator的第一个参数* "hello"这个String对象就作为第二个参数* String str = new String("str1");* str.compareTo("hello");  */Collections.sort(students, Student::sortByScore);//创建一个新的Student对象,使用lambda表达式创建//不接收参数,返回一个对象,其实就是Supplier接口的实例Supplier<Student> su1 = () -> new Student();//方法引用4---类名::newSupplier<Student> su2 = Student::new;//BiConsumer是Consumer的扩展,可以接受两个参数返回一个值BiConsumer<String, Integer> bc1 = (name,score) -> new Student(name,score);//替换上面的lambda表达式,需要接收两个参数,所以调用的是有参构造方法BiConsumer<String, Integer> bc2 = Student::new;}
}//定义一个学生实体类
class Student {private String name;private int score;public Student() {}public Student(String name, int score) {this.name = name;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public int sortByScore(Student stu) {return this.getScore() - stu.getScore();}public int sortByName(Student stu) {return this.getName().compareTo(stu.getName());}
}//定义一个学生排序工具类
class StudentSortUtil {public static int sortByScore(Student stu1, Student stu2) {return stu1.getScore() - stu2.getScore();}public static int sortByName(Student stu1, Student stu2) {return stu1.getName().compareTo(stu2.getName());}// 普通方法,创建对象才能调用public int sortByScoreInstance(Student stu1, Student stu2) {return stu1.getScore() - stu2.getScore();}// 普通方法,创建对象才能调用public int sortByNameInstance(Student stu1, Student stu2) {return stu1.getName().compareTo(stu2.getName());}
}

Stream:

Stream分为中间操作和终止操作,中间操作会继续返回一个新的流,终止操作返回一个结果。

一行代码中如果只有中间操作,则不会执行,只有遇见终止操作才会执行。

package java8;import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.stream.Stream;public class StreamDemo {public static void main(String[] args) {//Stream的使用//创建流,参数为可变参数Stream<Integer> stream = Stream.of(50,66,88);//将Stream转化为数组//Object[] array =  stream.toArray();//System.out.println(Arrays.toString(array));//筛选过滤条件,参数为Predicate,动作自己指定,找到大于60的数//流分为中间操作和终止操作,节点流会继续返回一个流对象,终止操作会返回一个结果,//只有中间流,代码不会执行,只有遇见终止操作才会执行//stream.filter((target) -> target > 60).forEach(System.out::println);//map对数据进行操作,接收一个Function实例 例:对流中的每个元素都乘以2stream.map((t) -> 2 * t).forEach(System.out::println);//流的无限模式,会对seed一直执行UnaryOperator的事件,一般和limit配合使用//skip(n)跳过n个元素,limit(n) 返回n个元素的流Stream.iterate(0, t -> t + 2).skip(2).limit(6).forEach(System.out::println);//将流转换为集合对象,第一个参数,传递一个Supplier 最终结果类型由此提供//第二个参数 BiConsumer() 传递两个参数,第一个要操作的集合,第二个当前的流元素//第三个元素BiConsumer() 传递两个集合,最终合并成一个集合//类似StringBuffer.append()方法
//      stream.collect(() -> new ArrayList<Integer>(),
//              (target,item)-> target.add(item),
//              (result,target)-> result.addAll(target)).forEach(System.out::println);//可以使用方法引用简化stream.collect(LinkedList::new,LinkedList::add,LinkedList::addAll);}
}

jdk1.8新特性初步学习相关推荐

  1. java 1.7 可变参数,JDK1.7新特性(2):异常和可变长参数处理

    异常 jdk1.7对try--catch--finally的异常处理模式进行了增强,下面我们依次来看增强的方面. 1. 为了防止异常覆盖,给Throwable类增加了addSuppressed方法,可 ...

  2. java基础知识总结:基础知识、面向对象、集合框架、多线程、jdk1.5新特性、IO流、网络编程

    目录 一.基础知识: 二.面向对象 三.集合框架 四.多线程: 五.jdk1.5的新特性 六.IO流 七.网络编程: 一.基础知识: 1.JVM.JRE和JDK的区别: JVM(Java Virtua ...

  3. JDK1.8 新特性(全)

    JDK1.8 新特性 本文主要介绍了JDK1.8版本中的一些新特性,乃作者视频观后笔记,仅供参考. jdk1.8新特性知识点: Lambda表达式 函数式接口 方法引用和构造器调用 Stream AP ...

  4. jdk1.8新特性的应用-Stream 的终止操作

    jdk1.8新特性的应用-Stream 的终止操作 public class TestStreamApi4 {List<Employee> emps = Arrays.asList(new ...

  5. jdk1.8新特性_Lambda表达式的引入

    jdk1.8新特性_Lambda表达式的引入 引入 需求: 获取工资大于20000的员工信息 public class Employee {private String name;private in ...

  6. jdk1.5新特性5之枚举之模拟枚举类型

    一 简单应用 package cn.xy.Enum; public enum TrafficLamp {  RED,GREEN,YELLOW; } TrafficLamp red = TrafficL ...

  7. JAVA day20、21 双列集合Map<K,V>:HashMap,LinkedHashMap,TreeMap,Hashtable, ConcurrentHashMap;JDK1.9新特性

    一.Map<K,V> Java提供了专⻔的集合类⽤来存放这种这种⼀⼀对应的关系,叫做映射对象,即 java.util.Map 接⼝. 类型参数: K - 此映射所维护的键的类型 V - 映 ...

  8. JDK1.6“新“特性Instrumentation之JavaAgent

    JDK1.6"新"特性Instrumentation之JavaAgent 文章目录 JDK1.6"新"特性Instrumentation之JavaAgent 简 ...

  9. 黑马程序员————高新技术————JDK1.5新特性

    ----------------------ASP.Net+Android+IOS开发----------------------期待与您交流! JDK1.5新特性 一:静态导入 l  Import语 ...

  10. JDK-1.5_新特性

    1.泛型(Generics) 泛型是JDK1.5中一个最"酷"的特征.通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能.在JD ...

最新文章

  1. 技术非中立,语言非同质:机器翻译正被用于维护文化障碍
  2. SAP EWM 性能优化(一)
  3. linux上java解加密(AES/CBC)异常:java.lang.SecurityException: JCE cannot authenticate the provider BC办法
  4. OpenCV中直方图均衡化
  5. 利用奇异值产生脆弱水印应用于检测、定位、恢复文章总结
  6. God of War Ascension / 战神4, 再一次迎来新导演!
  7. 深度学习2.0-19.随机梯度下降之可视化与实战
  8. 关于计算机用途的ppt,计算机组成与用途课件.ppt
  9. python中的时间和时区详解(datetime / dateutil / pytz)
  10. 【向生活低头】如何在Gold Wave软件中为声音添加背景音乐
  11. 蓝桥杯算法训练VIP-调和数列问题
  12. SpringMv的IOC控制反转以及DI依赖注入(SpringMvc⑨)
  13. 【pyqt5学习】—— 滑动条Qslider、计数器QSpinBox学习
  14. 小牛采购管理系统 v3.01 bt
  15. 工资3000,靠国际版抖音TikTok月入2W+:这个风口真的很赚钱!
  16. 视频知识普及:码率,分辨率,帧率,清晰度
  17. 脏读,幻读,幻行原因
  18. 2022年PMP考试题型都有什么?
  19. linux系统下 安装docker
  20. 如何将硬盘的分区大小设置为整数

热门文章

  1. Linux入门之文件与目录、用户、网络与服务、进程管理
  2. 7-3 jmu-Java-02基本语法-03-身份证排序 (4分)
  3. 《算法笔记》3.2小节——入门模拟->查找元素
  4. EventBus源码阅读
  5. letax para word使用说明
  6. Cisco设备的简介和IOS的备份、恢复、升级
  7. C#,入门教程(43)——字节、字符、字符串及操作函数之基础知识总结与实例源代码(2023清明之作)
  8. 记录|MacbookPro Shell|报错 cd: string not in pwd的解决办法
  9. 计算机学院开展活动,团学会 | 以梦为马,不负韶华 计算机学院开展“逐梦100”活动(二)...
  10. Java 【手写webserver】学习笔记