java8新特性
Java 8新特性简介
1.1 概述
Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。
Java 8 是oracle公司于2014年3月发布,可以看成是自Java 5 以来最具革命性的版本。Java 8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性。
1.2 目的
-
速度更快
-
代码更少(增加了新的语法:Lambda表达式)
-
强大的Stream API
-
最大化减少空指针异常:Optional
1.3 重要的新特性
-
函数式接口
-
Lambda表达式
-
方法引用
-
Stream API
-
Optional类
-
调用 Collections.sort()方法,通过定制排序比较两个 Employee(先按年龄比,年龄相同按姓名比),使用 Lambda 表达式作为参数传递。
package com.guotong.Test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /** * @program: baseend * @description: Mymain * @author: GuoTong * @create: 2020-08-26 20:29 **/ public class MyMain { public static void main(String[] args) { ArrayList<Employee> arrayList = new ArrayList<>(); arrayList.add(new Employee("GuoTong", 23)); arrayList.add(new Employee("Spring", 22)); arrayList.add(new Employee("BuoTong", 23)); arrayList.add(new Employee("Spring", 12)); arrayList.add(new Employee("GuoTong", 53)); arrayList.add(new Employee("Spring", -22)); /* //原始 Comparator<Employee> comparator = new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { if (o1.getAge() != o2.getAge()) return o1.getAge() - o2.getAge(); else return o1.getName().compareTo(o2.getName()); } }; Collections.sort(arrayList, comparator);*/ //lambda表达式 Collections.sort(arrayList, (o1, o2) -> { int age = o1.getAge() - o2.getAge(); if (age != 0) return age; else return o1.getName().compareTo(o2.getName()); }); arrayList.forEach(System.out::println); } }
-
① 声 明 函 数 式 接 口 , 接 口 中 声 明 抽 象 方 法 : public String getValue(String str);②声明类 LambdaTest,类中编写方法使用接口作为参数,将一个字符串转换成大写,并作为方法的返回值。③再将一个字符串的第 2 个到第 4 个索引位置进行截取子串。
package com.guotong.Test; /** * @program: baseend * @description: 函数式接口 * @author: GuoTong * @create: 2020-08-26 21:59 **/ @FunctionalInterface public interface InterfaceFunction { public String getValue(String str); } package com.guotong.Test; /** * @program: baseend * @description: 测试函数式接口 * @author: GuoTong * @create: 2020-08-26 22:02 **/ public class LambdaTest { public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest(); //转大写 String str1 = lambdaTest.changeCapital(str -> str.toUpperCase(), "guotong"); System.out.println(str1); //转小写 String str3 = lambdaTest.changeCapital(str -> str.toLowerCase(), "GuoTong"); System.out.println(str3); //切割2-5 String str2 = lambdaTest.changeCapital(str -> str.substring(2, 5), "Hello World"); System.out.println(str2); } //字母转大写 public String changeCapital(InterfaceFunction function,String value){ return function.getValue(value); } }
-
①声明一个带两个泛型的函数式接口,泛型类型为<T,R> : T 为参数,R 为返回值。②接口中声明对应抽象方法③在 LambdaTest 类中声明方法,使用接口作为参数,计算两个 long型参数的和。④再计算两个 long 型参数的乘积
package com.guotong.Test; /** * @program: baseend * @description: genericity 泛型 函数式接口 * @author: GuoTong * @create: 2020-08-26 22:16 **/ @FunctionalInterface public interface Genericity<R,T> { public R getValue(T one,T two); } package com.guotong.Test; /** * @program: baseend * @description: 测试函数式接口 * @author: GuoTong * @create: 2020-08-26 22:02 **/ public class LambdaTest { public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest(); //加法 Long aLong1 = lambdaTest.numberCrunching((o1, o2) -> o1 + o2, 10L, 20L); System.out.println(aLong1); Long aLong2 = lambdaTest.numberCrunching((o1, o2) -> o1 * o2, 10L, 20L); System.out.println(aLong2); //转大写 String str1 = lambdaTest.changeCapital(str -> str.toUpperCase(), "guotong"); System.out.println(str1); //转小写 String str3 = lambdaTest.changeCapital(str -> str.toLowerCase(), "GuoTong"); System.out.println(str3); //切割2-5 String str2 = lambdaTest.changeCapital(str -> str.substring(2, 5), "Hello World"); System.out.println(str2); } //字母转大写 public String changeCapital(InterfaceFunction function, String value) { return function.getValue(value); } //数值运算 public Long numberCrunching(Genericity<Long, Long> function, Long num1, Long num2) { return function.getValue(num1, num2); } }
-
给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?例如,给定【1,2,3,4,5】, 应该返回【1,4,9,16,25】。
package com.guotong.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.UnaryOperator; /** * @program: baseend * @description: 求数组每一个数的平方后的新数组 * @author: GuoTong * @create: 2020-08-26 22:28 **/ public class TestSum { public static void main(String[] args) { List<Integer> integers = Arrays.asList(5, 2, 8, 3, 4); integers.stream() .map(x -> x * x) .sorted((o1,o2)->o1-o2) .forEach(y->{ System.out.print(y + "\t"); }); } }
重点:
import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; /** * @program: FirstDemo * @description: Stream学习 * @author: GuoTong * @create: 2020-08-26 11:52 **/ public class StreamTest { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(10); list.add(72); list.add(35); list.add(-15); list.add(35); //1.创造流 //使用集合产生stream流:串行流 Stream<Integer> stream = list.stream();//普通流, //使用集合产生stream流:并行流 // Stream<Integer> integerStream = list.parallelStream(); //流的产生方式3 // Stream<String> stream1 = Stream.of("abc", "yyy", "hhh"); //流的产生方式,迭代器 //筛选和切片 //。需求,筛选/过滤出大于0的数 filter // stream.filter(i -> i > 0).forEach(System.out::println); //。需求,去除重复 distinct 注意:如果是对象:那这个类必须重写equals和hashCode // stream.distinct().forEach(System.out::println); //需求,先去除重复,然后赛选出大于的数。注意流可以链式执行 // stream.distinct().filter(i -> i >= 0).forEach(System.out::println); //需求。取出前三个元素 //stream.limit(3L).forEach(System.out::println); //需求。跳过前两个元素,把后面的元素取出来 // stream.skip(2L).forEach(System.out::println); //需求,让每一个元素乘以2,得到每一个元素乘以2的集合 //stream.map(i -> i * 2).forEach(System.out::println); //排序,自然排序 升序 //stream.sorted().forEach(i-> System.out.print(i+"\t")); //比较器排序:降序 //stream.sorted((i1,i2)->i2-i1).forEach(i-> System.out.print(i+"\t")); //判断集合中的每一个元素,是否都大于0 //System.out.println(stream.allMatch(x -> x > 0)); //判断集合中至少有一个大于零的数 // System.out.println(stream.anyMatch(x -> x > 0)); //得到第一个元素||德奥当前流的任意元素 /* Optional<Integer> first = stream.findFirst(); Integer integer1 = first.get(); System.out.println(integer1);*/ /*Optional<Integer> any = stream.findAny(); Integer integer = any.get(); System.out.println(integer);*/ /* //最大值||最小值||总数 System.out.println("流中个数"+list.stream().count()); // System.out.println("流中元素最大值:"+list.stream().max((i1,i2)->i1-i2).get()); System.out.println("流中元素最大值:"+list.stream().max(Integer::compareTo).get()); //System.out.println("流中元素最小值:"+list.stream().min((i1,i2)->i1-i2).get()); System.out.println("流中元素最小值:"+list.stream().min(Integer::compareTo).get());*/ //规约 1 // System.out.println(stream.reduce((i1, i2) -> i1 + i2).get()); //归约 2 // System.out.println(stream.reduce(10,(i1, i2) -> i1 + i2)); //收集成一个集合 // Set<Integer> collect = stream.filter(i -> i > 0).collect(Collectors.toSet()); //List<Integer> collect1 = stream.filter(i -> i > 0).collect(Collectors.toList()); //迭代器产生流求1-100和 //Integer integer = Stream.iterate(1, i -> i+1).limit(100L).reduce((i1, i2) -> i1 + i2).get(); //System.out.println(integer); //2.流的使用 //3.关闭流 } //流里面放流,把多个流合成一个流 public void getTwoStream() { IntStream stream1 = Arrays.stream(new int[]{1, 2, 3, 4, 6}); IntStream stream2 = Arrays.stream(new int[]{3, 7, 8, 5, 9}); Stream<IntStream> stream = Stream.of(stream1, stream2); //把几个流变成一个流: stream.flatMapToInt(s -> s.map(i -> i)).forEach(System.out::println); } }
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Comparator; import java.util.TreeSet; /** * @program: FirstDemo * @description: java8新特性:lambda表达式 * @author: GuoTong * @create: 2020-08-26 10:05 **/ public class TestLambda { //函数式编程 public static void main(String[] args) { //原始 new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(i); } } }).start(); //lambda:前提是函数式接口:接口里面只有一个方法。 new Thread(() -> { for (int i = 110; i < 120; i++) { System.out.println(i); } }).start(); } } @Data @NoArgsConstructor @AllArgsConstructor class Student { private String name; private int age; private int score; } class TestStudent { public static void main(String[] args) { //原始 /* Comparator<Student> comparator = new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.getScore()-o2.getScore(); } };*/ //简化:lambda是对匿名对象的一种语法层面的简化 /* * **左侧:**指定了 Lambda 表达式需要的**参数列表** **右侧:**指定了 **Lambda** **体**,是抽象方法的实现逻辑,也即Lambda 表达式要执行的功能。*/ Comparator<Student> comparator = (o1, o2) -> o1.getScore() - o2.getScore(); TreeSet<Student> students = new TreeSet<>(comparator); students.add(new Student("lsii", 19, 60)); students.add(new Student("asii", 40, 90)); students.add(new Student("vdii", 50, 40)); students.add(new Student("gdii", 13, 97)); students.forEach(System.out::println); //方法引用 //只需要告诉Java引用代替的方法在哪里:替代方法的返回值和参数列表要一致。 //格式 类 :: 静态方法||对象 ::实例方法。最多的:forEach(System.out::println); } } @FunctionalInterface//检测是不是函数式接口,接口中有且只有一个必须被实现的抽象方法。 interface AliBaBa{ void fly(); boolean equals(Object obj);//这个不算必须被实现的接口哦 }
Optional
import java.util.Optional; /** * @program: FirstDemo * @description: Optional学习 * @author: GuoTong * @create: 2020-08-26 15:35 **/ public class OptionalTest { public static void main(String[] args) { //Optional的创建的三宗方式 //1 Optional.of不能传递进去null,会报空指针异常 Optional<Student> student = Optional.of(new Student("tom", 23, 92)); //2 Optional<Student> empty = Optional.empty(); //3 Optional<Student> obj = Optional.ofNullable(null); //判断Optional容器是不是存在对象 boolean b = student.isPresent(); //打印 student.ifPresent(student1 -> System.out.println(student1)); } }
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
Java入门到入坟
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南