JDK1.8新特性1

JDK1.8新特性1

  • JDK1.8新特性:
    • Lambda表达式:
      • 使用:
        • 无参数无返回值:
        • 单参数无返回值:
        • 多参数无返回值:
        • 多参数有返回值:
      • 案例:
        • 案例1:
        • 案例2:
        • 案例3:
    • 函数式接口:
      • 四大核心函数式接口:
        • 衍生接口:
        • 使用:
          • 使用1:
          • 使用2:
    • 方法、构造方法和数组引用:
      • 方法引用:
        • 对象::实例方法
        • 类名::静态方法
        • 类名::实例方法
      • 构造方法引用:
      • 数组引用:

JDK1.8新特性:

  1. 速度更快 - 优化底层源码,比如HashMap、ConcurrentHashMap。
  2. 代码更少 - 添加新的语法Lambda表达式。
  3. 强大的Stream API。
  4. 便于并行。
  5. 最大化减少空指针异常 - Optional。

 
 

Lambda表达式:

Lambda是一个匿名函数(方法), 允许把函数作为一个方法的参数 。
 
作用:

​        1. 一般都是优化匿名内部类。

​        2. 利用Lambda表达式可以写出更简洁、更灵活的代码。

 

使用:

tips:

  1. 重写方法的形参只有一个时,可以不加小括号。
  2. Lambda表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
  3. Lambda表达式中访问外层的局部变量,外层的局部变量自动变成隐式常量,默认添加final。
  4. 重写方法的形参同时加类型或同时不加类型。

 

无参数无返回值:

当匿名内部类中只有一个方法时。

public interface I1 {public void method();
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method() {System.out.println("使用传统匿名内部类的方式");}};i1.method();//当匿名内部类中只有一个方法时,才能使用lambda表达式这样简化。I1 i2 = ()->{System.out.println("使用lambda表达式的方式");};i2.method();//当匿名内部类中只有一个方法时,才能使用lambda表达式这样简化。I1 i3 = ()->System.out.println("使用lambda表达式的方式");i3.method();}
}

 
 

单参数无返回值:

当匿名内部类中只有一个方法,且该方法只有一个参数。

public interface I1 {public void method(String str);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str) {System.out.println("使用传统匿名内部类的方式:" + str);}};i1.method("今天天气真好!");I1 i2 = (String str)->{System.out.println("使用lambda表达式的方式:" + str);};i2.method("今天天气真好!");I1 i3 = (String str)->System.out.println("使用lambda表达式的方式:" + str);i3.method("今天天气真好!");//省略参数的数据类型I1 i3 = (str)->System.out.println("使用lambda表达式的方式:" + str);i3.method("今天天气真好!");//省略方法的小括号//方法的形参只有一个时,可以不加小括号。I1 i4 = str->System.out.println("使用lambda表达式的方式:" + str);i4.method("今天天气真好!");}
}

 
 

多参数无返回值:

当匿名内部类中只有一个方法,且该方法只有多个参数。

public interface I1 {public void method(String str,int i);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str, int i) {System.out.println("使用传统匿名内部类的方式:" + str + " -- " + i);}};i1.method("今天天气真好!", 666);I1 i2 = (String str,int i)->{System.out.println("使用lambda表达式的方式:" + str + " -- " + i);};i2.method("今天天气真好!", 777);I1 i3 = (String str,int i)->System.out.println("使用lambda表达式的方式:" + str + " -- " + i);i3.method("今天天气真好!", 888);//多个参数时,参数的数据类型要么全部去掉,要么全部保留。I1 i4 = (str, i)->System.out.println("使用lambda表达式的方式:" + str + " -- " + i);i4.method("今天天气真好!", 999);}
}

多个参数时,参数的数据类型要么全部去掉,要么全部保留。

 
 

多参数有返回值:

当匿名内部类中只有一个方法,且该方法只有多个参数,且有返回值时。

public interface I1 {public String method(int a,int b);
}
public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic String method(int a, int b) {return "使用传统匿名内部类的方式:" + (a+b);}};String method = i1.method(10, 10);System.out.println(method);I1 i2 = (int a,int b)->{return "使用lambda表达式的方式:" + (a+b);};String method = i2.method(20, 20);System.out.println(method);I1 i3 = (a, b)-> "使用lambda表达式的方式:" + (a+b);String method = i3.method(30, 30);System.out.println(method);}
}

 
 

案例:

案例1:

调用Collections.sort()方法,通过定制排序比较两个Student对象(先按年龄比较,年龄相同按照薪资比较),使用Lambda表达式作为参数传递。

//枚举
public enum Course {JAVA,HTML,PYTHON;
}
public class Student {private String name;private int age;private double salary;private Course course;public Student() {}public Student(String name, int age, double salary, Course course) {this.name = name;this.age = age;this.salary = salary;this.course = course;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((course == null) ? 0 : course.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());long temp;temp = Double.doubleToLongBits(salary);result = prime * result + (int) (temp ^ (temp >>> 32));return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Student other = (Student) obj;if (age != other.age)return false;if (course != other.course)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))return false;return true;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder();builder.append("Student [name=");builder.append(name);builder.append(", age=");builder.append(age);builder.append(", salary=");builder.append(salary);builder.append(", course=");builder.append(course);builder.append("]");return builder.toString();}}
public static void main(String[] args) {List<Student> stuList = Arrays.asList(new Student("张三", 28, 4800,Course.JAVA),new Student("李四", 36, 7200,Course.JAVA),new Student("王五", 19, 9600,Course.HTML),new Student("赵六", 42, 6100,Course.HTML),new Student("孙七", 23, 9600,Course.PYTHON),new Student("吴八", 28, 3000,Course.PYTHON));//匿名内部类的方式
//		Collections.sort(stuList, new Comparator<Student>() {
//			@Override
//			public int compare(Student o1, Student o2) {
//				if(o1.equals(o2)){
//					return 0;
//				}
//				
//				int compare = Integer.compare(o1.getAge(), o2.getAge());
//				if(compare != 0){
//					return compare;
//				}
//				
//				return Double.compare(o1.getSalary(), o2.getSalary());
//			}
//		});Collections.sort(stuList, (o1,o2)->{if(o1.equals(o2)){return 0;}int compare = Integer.compare(o1.getAge(), o2.getAge());if(compare != 0){return compare;}return Double.compare(o1.getSalary(), o2.getSalary());});for (Student stu : stuList) {System.out.println(stu);}}

 
 

案例2:

创建I1接口,创建抽象方法:public String getValue(String str),在测试类中编写方法使用接口作为参数,将一个字符串转为大写,并作为方法的返回值。

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)-> {return x.toUpperCase();});System.out.println(str);}public static String method(String str,I1 i1){return i1.getValue(str);}
}interface I1{public String getValue(String str);
}

 
 

案例3:

创建I1<T,R>接口,泛型T为参数,R为返回值,创建抽象方法:public R add(T t1,T t2),在测试类中编写方法使用接口作为参数,计算两个long类型的和。

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,I1<Long,Long> i1){return i1.add(l1, l2);}
}interface I1<T,R>{public R add(T t1,T t2);
}

 
 
 

函数式接口:

​ 函数式接口:是指仅仅只包含一个抽象方法的接口,jdk1.8提供了一个@FunctionalInterface注解来定义函数式接口,如果我们定义的接口不符合函数式的规范便会报错。配合Lambda表达式一起使用。

 
 

四大核心函数式接口:

​ 应用场景:当项目中需要一个接口,并且该接口中只有一个抽象方法,就没必要去创建新的接口,直接选择Java提供的使用合适的函数式接口即可。

函数式接口参数类型返回类型用途
Consumer 消费型接口Tvoidvoid accept(T t);
Supplier 供给型接口voidTT get();
Function<T, R> 函数型接口TRR apply(T t);
Predicate 断言型接口Tbooleanbooelan test(T t);

 

衍生接口:
函数式接口参数类型返回类型用途
BiConsumer<T, U>T,Uvoid对类型为T,U参数应用操作。包含方法为void accept(T t,U u);
BiFunction<T, U, R>T,UR对类型为T,U参数应用操作,并返回R类型的结果。包含方法为R apply(T t,U u);
UnaryOperator extends Function<T, T>TT对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为T apply(T t);
BinaryOperator extends BiFunction<T,T,T>T,TT对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为T apply(T t1,T t2);
ToIntFunction ToLongFunction ToDoubleFunctionTint long double分别计算int、long、double值的函数
IntFunction LongFunction DoubleFunctionint long doubleR参数为int、long、double类型的函数

 
 
 

使用:
使用1:

创建I1接口,创建抽象方法:public String getValue(String str),在测试类中编写方法使用接口作为参数,将一个字符串转为大写,并作为方法的返回值。

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)-> {return x.toUpperCase();});System.out.println(str);}//Function函数式接口public static String method(String str,Function<String, String> fun){//apply函数式接口的方法return fun.apply(str);}
}

 
 
再更新:

public class Test01 {public static void main(String[] args) {String str = method("abc", (x)->{return x.toUpperCase();});System.out.println(str);}//UnaryOperator函数式接口public static String method(String str,UnaryOperator<String> uo){apply函数式接口的方法return uo.apply(str);}
}

 
 
 

使用2:

创建I1<T,R>接口,泛型T为参数,R为返回值,创建抽象方法:public R add(T t1,T t2),在测试类中编写方法使用接口作为参数,计算两个long类型的和。

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,BiFunction<Long,Long,Long> bf){return bf.apply(l1, l2);}
}

 
 

再更新:

public class Test01 {public static void main(String[] args) {long addLong = addLong(100,200,(a,b)->{return a+b;});System.out.println(addLong);}public static long addLong(long l1,long l2,BinaryOperator<Long> bo){return bo.apply(l1, l2);}
}

 
 
 

方法、构造方法和数组引用:

方法、构造方法和数组引用就是Lambda的另一种表现形式,可以简化Lambda表达式。

 
 

方法引用:

若Lamdba表达式中的内容由方法已经实现了,可以使用方法引用这个技能,当你需要使用方法引用时,目标引用放在分隔符::前,方法的名称放在后面。

 

对象::实例方法

Lambda表达式中调用方法的参数类型和返回值必须和函数式接口中的抽象方法一致。

public class Test01 {public static void main(String[] args) {I1 i1 = new I1() {@Overridepublic void method(String str) {//println方法无返回值,一个参数,参数类型是StringSystem.out.println(str);}};i1.method("今天天气真好!");I1 i2 = (str)->System.out.println(str);i2.method("今天天气真好!");// 因为  method方法无返回值,一个参数,参数类型是String,//且println方法无返回值,一个参数,参数类型是String//故可以使用方法的引用I1 i3 = System.out::println;i3.method("今天天气真好!");}
}interface I1{//method无返回值,一个参数,参数类型是Stringpublic void method(String str);
}

因为 method 方法无返回值,一个参数,参数类型是 String ,且 println 方法无返回值,一个参数,参数类型是 String ,一 一对应,故可以使用方法的引用。

 
 

类名::静态方法

Lambda表达式中调用方法的参数类型和返回值必须和函数式接口中的抽象方法一致。

public class Test01 {public static void main(String[] args) {Comparator<Integer> comparator = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1, o2);}};int compare1 = comparator.compare(10, 20);System.out.println(compare1);Comparator<Integer> comparator = (o1,o2)-> Integer.compare(o1, o2);int compare2 = comparator.compare(10, 20);System.out.println(compare2);Comparator<Integer> comparator = Integer::compare;int compare3 = comparator.compare(10, 20);System.out.println(compare3);}
}

 
 

类名::实例方法

​ Lambda表达式参数列表中第一个参数必须是实例方法的调用者,第二个参数必须是实例方法的参数

public class Test01 {public static void main(String[] args) {I1<String> i1 = new I1<String>() {@Overridepublic boolean method(String t1, String t2) {return t1.equals(t2);}};boolean method = i1.method("abc", "abc");System.out.println(method);I1<String> i2 = (str1,str2)->str1.equals(str2);boolean method2 = i2.method("abc", "abc");System.out.println(method2);//重写method方法,该方法的第一个参数调用equals,第二个参数是传入equals里的数据I1<String> i3 = String::equals;boolean method3 = i3.method("abc", "abc");System.out.println(method3);}
}interface I1<T>{public boolean method(T t1,T t2);
}

 
 

构造方法引用:

类名::new

需要调用的构造方法的参数列表必须和函数式接口中抽象方法的参数列表一致。

public class Test01 {public static void main(String[] args) {I1 i = new I1() {@Overridepublic Student method() {return new Student();}};Student st = i.method();System.out.println(st);//调用无参构造去创建学生对象//I1的method方法无参数I1 i1 = Student::new;Student stu1 = i1.method();System.out.println(stu1);//调用有参构造去创建学生对象//I2的method方法有参数I2 i2 = Student::new;Student stu2 = i2.method("小明", 23, 12000, Course.JAVA);System.out.println(stu2);}
}
interface I1{public Student method();
}
interface I2{public Student method(String name, int age, double salary, Course course);
}

 
 

数组引用:

type[]::new

public class Test01 {public static void main(String[] args) {//参数            方法里面的语句I1<String[]> i = (capacity)->new String[capacity];String[] s = i.method(3);System.out.println(Arrays.toString(s));I1<String[]> i1 = String[]::new;String[] ss = i1.method(3);System.out.println(Arrays.toString(ss));}
}interface I1<T>{public T method(int capacity);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/20635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录训练营Day 42|力扣62.不同路径、63. 不同路径 II

1.不同路径 代码随想录 视频讲解&#xff1a;动态规划中如何初始化很重要&#xff01;| LeetCode&#xff1a;62.不同路径_哔哩哔哩_bilibili 代码&#xff1a; class Solution { public:int uniquePaths(int m, int n) {// dp[i][j] 表示从起点走到坐标为i&#xff0c;j的地方…

全自动打包封箱机:解析其在产品质量与安全保障方面的作用

在当今快节奏的生产环境中&#xff0c;全自动打包封箱机以其高效、精准的特点&#xff0c;正逐渐成为生产线上的得力助手。它不仅提升了生产效率&#xff0c;更在产品质量与安全保障方面发挥着举足轻重的作用。星派将详细解析全自动打包封箱机在产品质量与安全保障方面的作用。…

css简单介绍

1.css介绍 css指的是层叠样式(Cascadingstyle sheets)&#xff0c;是用来给HTML标签添加样式的语言。他可以设置HTML页面中 文字大小&#xff0c;颜色&#xff0c;对齐方式及元素的 宽高&#xff0c; 位置 等样式。 一个完整的网页是由HTML、CSS、Javascript三部分组成。HT…

CLIP--Learning Transferable Visual Models From Natural Language Supervision

参考&#xff1a;CLIP论文笔记--《Learning Transferable Visual Models From Natural Language Supervision》_visual n-grams模型-CSDN博客 openAI&#xff0c;2021&#xff0c;将图片和文字联系在一起&#xff0c;----->得到一个能非常好表达图片和文字的模型主题&#…

网络安全-钓鱼篇-利用cs进行钓鱼

一、环境 自行搭建&#xff0c;kill&#xff0c;Windows10&#xff0c;cs 二、原理 如图所示 三、钓鱼演示 首先第一步&#xff1a;打开System Profiler-分析器功能 选择克隆www.baidu.com页面做钓鱼 之后我们通过包装域名&#xff0c;各种手段让攻击对象访问&#xff1a;h…

Java面试题:Redis1_Redis的使用场景和如何解决Redis缓存穿透问题

Redis使用场景常见问题 缓存 缓存三兄弟(穿透,击穿,雪崩) 双写一致 持久化 数据过期策略 数据淘汰策略 分布式锁 setnx,redisson 消息队列,延迟队列 … 解决Redis缓存穿透问题 缓存穿透问题 请求->redis缓存->mysql数据库 当一个新请求到来时,先会访问redi…

JVM(Java虚拟机)笔记

面试常见&#xff1a; 请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?什么是OOM&#xff0c;什么是栈溢出StackOverFlowError? 怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取&#xff1f;怎么分析Dump文件&#xff1f;谈谈JVM中&#xff0c;类加载器你的认识…

前端最新面试题(基础模块HTML/CSS/JS篇)

目录 一、HTML、HTTP、WEB综合问题 1 前端需要注意哪些SEO 2 img的title和alt有什么区别 3 HTTP的几种请求方法用途 4 从浏览器地址栏输入url到显示页面的步骤 5 如何进行网站性能优化 6 HTTP状态码及其含义 7 语义化的理解 8 介绍一下你对浏览器内核的理解? 9 html…

【C++】vector常见的使用方式

前言&#xff1a;在上一篇中我们讲到了string类的模拟实现&#xff0c;今天我们将进一步的去学习vector的一些常用的使用方法。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &#x1f448; &#x1f4af;代码仓…

命运方舟台服注册 命运方舟台服怎么注册?不会操作看这里

命运方舟台服注册 命运方舟台服怎么注册&#xff1f;不会操作看这里 命运方舟作为今年备受瞩目的一款MMORPG类型游戏&#xff0c;在上线前的预约数量已经一次又一次创下新高。这款游戏的开发商Smile gate真是给玩家们带来了一款让人眼前一亮的作品。游戏创建在虚幻引擎的基础…

USACO 2019 December Contest, BronzeProblem 2. Where Am I? 题解

这道题目通过例子可以看出查找最长的相同子串&#xff0c;下一个长度如果没有找到相同的子串就是结果&#xff0c;需要写三个循环&#xff0c;第一个循环是是否存在长度为len的相同子串&#xff0c;第二个循环是从左往右截取长度为len的子串&#xff0c;第三个循环的条件是j<…

用esp prog烧录ESP32-C3板踩坑

附ESP32C3的GPIO一览&#xff1a; vscode选择Jtag烧录&#xff0c;终端输出esp_usb_jtag: could not find or open device&#xff1a; D:\Devtools\Espressif\tools\openocd-esp32\v0.12.0-esp32-20230921\openocd-esp32\bin\openocd.exe -f board/esp32s3-builtin.cfgOpen O…

【电路笔记】-带阻滤波器

带阻滤波器 文章目录 带阻滤波器1、概述2、典型带阻滤波器配置3、带阻滤波器示例14、陷波滤波器5、带阻滤波器示例26、总结带阻滤波器也称为陷波滤波器,阻止并拒绝位于其两个截止频率点之间的频率,并传递该范围两侧的所有这些频率。 1、概述 通过将基本 RC 低通滤波器与 RC …

Docker基础命令(三)

同步docker容器中的时间和本地时间一致 背景: 在很多时候, 训练模型的时候, 记录的log日志中标记的时间和实际的时间不一致, 往往是容器时间和本地时间不一致照成的. 方案 场景一: 正在运行的容器&#xff0c;可以宿主机直接执行命令给某个容器同步时间 #方法1 直接在宿主机…

ElasticSearch教程(详解版)

本篇博客将向各位详细介绍elasticsearch&#xff0c;也算是对我最近学完elasticsearch的一个总结&#xff0c;对于如何在Kibana中使用DSL指令&#xff0c;本篇文章不会进行介绍&#xff0c;这里只会介绍在java中如何进行使用&#xff0c;保证你看完之后就会在项目中进行上手&am…

Arduino烧录esp8266

default_encoding: cp936 Assume aggressive ‘core.a’ caching enabled. Note: optional global include file ‘arduino_modified_sketch_764314\Blink.ino.globals.h’ does not exist. Read more at https://arduino-esp8266.readthedocs.io/en/latest/faq/a06-global-bui…

【计划】装修相关感想

计划 Summary 从去年年底开始规划、设计、落实家里的装修&#xff0c;2024年4月正式开始装修&#xff0c;一个人探索和学习了很多知识和概念。 准备把这些东西做一些记录和分享&#xff0c;一方面记录一些装修的流程和中间的小细节便于第二次装修的时候避免&#xff1b;另一方…

Android设备实时监控蓝牙的连接、配对、开关3种状态

一、简介 Android设备&#xff0c;需要实时监控本机蓝牙连接其他蓝牙设备的状态&#xff0c;包含&#xff1a;连接、配对、开关3种状态。本文介绍了2种方法&#xff0c;各有优势&#xff0c;下面来到我的Studio一起瞅瞅吧~ 二、定时器任务 Handler 功能方法 定时器任务 Hand…

写字静不下心?不如试试这些“笨方法”

夏天悄悄热起来啦&#xff5e;有人说&#xff0c;想踏踏实实写一会儿&#xff0c;但又静不下心&#xff0c;耐不住性子&#xff0c;快收下这四个小锦囊&#xff0c;与古人一起笨拙精进吧&#xff01;    1、不论输赢      每次课前&#xff0c;暄桐林曦老师总会强调&am…

AlloyTeam Web前端大会:深入探索前端的无限可能

AlloyTeam Web前端大会&#xff1a;深入探索前端的无限可能 在数字化浪潮的推动下&#xff0c;Web前端技术日新月异&#xff0c;成为引领行业发展的重要力量。AlloyTeam Web前端大会作为业界的盛会&#xff0c;汇聚了众多前端领域的精英&#xff0c;共同探讨前端的未来发展趋势…