版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章
Java8及以上版本新特性
CONTENTS目录4.3Optional类4.2StreamAPI4.1Lambda表达式4.4Java21特性4.5反射本章内容随着Java8及以上版本的发布,Java语言经历了一次重要的转型,尤其在函数式编程和简化代码方面取得了显著的进步。本章内容重点介绍Java8及以上版本的新特性,包括Lambda表达式、StreamAPI、Optional类、Java21特性以及反射的应用。这些特性不仅提升了开发效率,也使得Java在处理并发、集合操作、空值处理等方面变得更加灵活和高效。学习目标了解:Lambda表达式的语法及其在Java中简化代码的作用;StreamAPI的概念以及它与传统集合操作的区别;Optional类的用途及如何避免空指针异常;Java21引入的新特性,特别是虚拟线程、结构化并发和sealed类等;反射的基本概念及其用途。理解:Lambda表达式如何实现函数式接口,简化传统匿名类的使用;StreamAPI中常用的操作符,如filter()、map()、reduce()、collect()等;如何使用Optional处理可能为null的值,避免空值带来的问题;Java21新特性如何简化并发编程,提升多线程任务的执行效率;如何使用反射API的常用方法,如获取类的元数据、动态加载类、创建对象、调用方法等。掌握:Lambda表达式在集合操作中的应用,如排序、过滤和映射等操作;StreamAPI的链式操作,如数据的过滤、变换和聚合;通过Optional类处理默认值和空值的情况;record类、sealed类和patternmatching等新特性的语法及应用场景;反射的性能影响和应用场景。运用:将Lambda表达式、StreamAPI、Optional类和Java21特性结合使用,在实际项目中提升代码的简洁性、可读性、执行效率以及程序的健壮性。4.1Lambda表达式Lambda表达式主要讲解基本的Lambda表示式、接收参数的Lambda表达式、带多个语句的Lambda表达式等内容,并且基于这些内容设计一个综合案例。4.1.1Lambda表达式的基础知识-1.Lambda表达式简介Lambda表达式是一种匿名函数,它可以通过更简洁的方式来表示一个方法或一个函数接口的实现。Lambda表达式使得代码更加简洁,尤其在集合处理、事件监听等场景中常常被使用。Lambda表达式的基本语法格式如下:(parameters)->expressionparameters:方法参数列表(可以省略参数类型)。->:Lambda运算符,表示“给定某些输入,产生某个输出”。expression:表达式体,可以是一个单一表达式或者是多个语句块。(1)基本的Lambda表达式4.1.1Lambda表达式的基础知识-1.Lambda表达式简介publicclassLambdaExample{publicstaticvoidmain(String[]args){//使用Lambda表达式实现Runnable接口Runnabler=()->System.out.println("Hello,Lambda!");r.run();//输出:Hello,Lambda!}}(2)接受参数的Lambda表达式式4.1.1Lambda表达式的基础知识-1.Lambda表达式简介importjava.util.function.BinaryOperator;publicclassLambdaExample1{publicstaticvoidmain(String[]args){//使用Lambda表达式实现一个加法操作BinaryOperator<Integer>add=(a,b)->a+b;System.out.println("Sum:"+add.apply(5,3));//输出:Sum:8}}(3)带有多个语句的Lambda表达式4.1.1Lambda表达式的基础知识-1.Lambda表达式简介importjava.util.function.Consumer;publicclassLambdaExample2{publicstaticvoidmain(String[]args){//使用Lambda表达式实现一个打印字符串和长度的方法Consumer<String>printDetails=str->{System.out.println("String:"+str);System.out.println("Length:"+str.length());};printDetails.accept("Hello,Lambda!");//输出:String:Hello,Lambda!//Length:13}}4.1.2Lambda表达式的综合案例01实验名称:JavaLambda表达式应用案例02实验目的•了解Lambda表达式的基本语法。•掌握Lambda表达式在集合、流操作、事件处理等方面的应用。•熟悉Java8中引入的函数式接口及其使用。•实践Lambda表达式的应用,解决实际问题。03实验内容•使用Lambda表达式对集合进行常见的操作(如遍历、过滤、排序、映射等)。•使用Lambda表达式结合StreamAPI对数据进行处理。•实现一个简单的事件监听器应用,使用Lambda表达式简化事件处理代码。•使用Lambda表达式实现自定义函数式接口。(1)Lambda表达式基础操作任务描述:通过Lambda表达式对一个整数列表进行遍历、过滤和排序操作。操作步骤:①
创建一个包含整数的List集合。②
使用Lambda表达式遍历集合,输出所有数字。③
使用Lambda表达式过滤出大于10的数字,并输出。④
使用Lambda表达式对集合进行排序,并输出排序后的结果。4.1.2Lambda表达式的综合案例-importjava.util.*;publicclassLambdaBasicExample{publicstaticvoidmain(String[]args){//创建一个整数集合List<Integer>numbers=Arrays.asList(5,12,8,21,3,15);//使用Lambda表达式遍历集合System.out.println("遍历集合:");numbers.forEach(n->System.out.print(n+""));实验步骤04(1)Lambda表达式基础操作任务描述:通过Lambda表达式对一个整数列表进行遍历、过滤和排序操作。操作步骤:①
创建一个包含整数的List集合。②
使用Lambda表达式遍历集合,输出所有数字。③
使用Lambda表达式过滤出大于10的数字,并输出。④
使用Lambda表达式对集合进行排序,并输出排序后的结果。4.1.2Lambda表达式的综合案例-实验步骤04//使用Lambda表达式过滤出大于10的数字System.out.println("\n\n大于10的数字:");numbers.stream().filter(n->n>10).forEach(n->System.out.print(n+""));//使用Lambda表达式对集合进行排序System.out.println("\n\n排序后的数字:");numbers.stream().sorted((a,b)->a-b).forEach(n->System.out.print(n+""));}}(2)使用StreamAPI结合Lambda表达式任务描述:使用StreamAPI与Lambda表达式进行复杂的数据处理(如分组、聚合、映射等)。操作步骤:①
创建一个包含学生信息(姓名和成绩)的List集合。②
使用Stream和Lambda表达式实现以下功能:•获取成绩大于80分的学生。•按照成绩降序排序学生。•计算所有学生的平均成绩。•将学生姓名转换为大写字母。4.1.2Lambda表达式的综合案例-实验步骤04importjava.util.*;classStudent{Stringname;intscore;Student(Stringname,intscore){=name;this.score=score;}}publicStringgetName(){returnname;}publicintgetScore(){returnscore;}@OverridepublicStringtoString(){returnname+":"+score;}}(2)使用StreamAPI结合Lambda表达式任务描述:使用StreamAPI与Lambda表达式进行复杂的数据处理(如分组、聚合、映射等)。操作步骤:①
创建一个包含学生信息(姓名和成绩)的List集合。②
使用Stream和Lambda表达式实现以下功能:•获取成绩大于80分的学生。•按照成绩降序排序学生。•计算所有学生的平均成绩。•将学生姓名转换为大写字母。4.1.2Lambda表达式的综合案例-实验步骤04publicclassLambdaStreamExample{publicstaticvoidmain(String[]args){//创建学生对象集合List<Student>students=Arrays.asList(newStudent("Alice",85),newStudent("Bob",70),newStudent("Charlie",95),newStudent("David",60),newStudent("Eve",75));
//获取成绩大于80的学生System.out.println("成绩大于80的学生:");students.stream().filter(s->s.getScore()>80).forEach(s->System.out.println(s));(2)使用StreamAPI结合Lambda表达式任务描述:使用StreamAPI与Lambda表达式进行复杂的数据处理(如分组、聚合、映射等)。操作步骤:①
创建一个包含学生信息(姓名和成绩)的List集合。②
使用Stream和Lambda表达式实现以下功能:•获取成绩大于80分的学生。•按照成绩降序排序学生。•计算所有学生的平均成绩。•将学生姓名转换为大写字母。4.1.2Lambda表达式的综合案例-实验步骤04//按成绩降序排序System.out.println("\n按成绩降序排序:");students.stream().sorted((s1,s2)->Ipare(s2.getScore(),s1.getScore())).forEach(s->System.out.println(s));(2)使用StreamAPI结合Lambda表达式任务描述:使用StreamAPI与Lambda表达式进行复杂的数据处理(如分组、聚合、映射等)。操作步骤:①
创建一个包含学生信息(姓名和成绩)的List集合。②
使用Stream和Lambda表达式实现以下功能:•获取成绩大于80分的学生。•按照成绩降序排序学生。•计算所有学生的平均成绩。•将学生姓名转换为大写字母。4.1.2Lambda表达式的综合案例-实验步骤04//计算所有学生的平均成绩doubleaverageScore=students.stream().mapToInt(Student::getScore).average().orElse(0);System.out.println("\n所有学生的平均成绩:"+averageScore);(2)使用StreamAPI结合Lambda表达式任务描述:使用StreamAPI与Lambda表达式进行复杂的数据处理(如分组、聚合、映射等)。操作步骤:①
创建一个包含学生信息(姓名和成绩)的List集合。②
使用Stream和Lambda表达式实现以下功能:•获取成绩大于80分的学生。•按照成绩降序排序学生。•计算所有学生的平均成绩。•将学生姓名转换为大写字母。4.1.2Lambda表达式的综合案例-实验步骤04//将学生姓名转换为大写字母System.out.println("\n学生姓名大写:");students.stream().map(s->s.getName().toUpperCase()).forEach(System.out::println);}}(3)Lambda表达式用于事件处理任务描述:使用Lambda表达式简化事件监听器的编写。操作步骤:①
创建一个按钮类,模拟按钮点击事件。②
使用Lambda表达式实现按钮点击事件的处理。4.1.2Lambda表达式的综合案例-实验步骤04interfaceButtonClickListener{voidonClick();}(3)Lambda表达式用于事件处理任务描述:使用Lambda表达式简化事件监听器的编写。操作步骤:①
创建一个按钮类,模拟按钮点击事件。②
使用Lambda表达式实现按钮点击事件的处理。4.1.2Lambda表达式的综合案例-实验步骤04classButton{privateButtonClickListenerlistener;publicvoidsetOnClickListener(ButtonClickListenerlistener){this.listener=listener;}publicvoidclick(){if(listener!=null){listener.onClick();}}}(3)Lambda表达式用于事件处理任务描述:使用Lambda表达式简化事件监听器的编写。操作步骤:①
创建一个按钮类,模拟按钮点击事件。②
使用Lambda表达式实现按钮点击事件的处理。4.1.2Lambda表达式的综合案例-实验步骤04publicclassLambdaEventExample{publicstaticvoidmain(String[]args){Buttonbutton=newButton();//使用Lambda表达式简化事件处理button.setOnClickListener(()->System.out.println("按钮被点击!"));//模拟按钮点击button.click();}}((4)自定义函数式接口与Lambda表达式任务描述:创建一个自定义的函数式接口,并使用Lambda表达式来实现该接口。操作步骤:①
创建一个函数式接口,定义一个方法(如计算两个数的和)。②
使用Lambda表达式实现该接口,并执行操作。4.1.2Lambda表达式的综合案例-实验步骤04interfaceAddOperation{intadd(inta,intb);}((4)自定义函数式接口与Lambda表达式任务描述:创建一个自定义的函数式接口,并使用Lambda表达式来实现该接口。操作步骤:①
创建一个函数式接口,定义一个方法(如计算两个数的和)。②
使用Lambda表达式实现该接口,并执行操作。4.1.2Lambda表达式的综合案例-实验步骤04publicclassLambdaFunctionInterfaceExample{publicstaticvoidmain(String[]args){//使用Lambda表达式实现AddOperation接口AddOperationadd=(a,b)->a+b;//执行加法操作intresult=add.add(5,10);System.out.println("5+10="+result);//输出5+10=15}}4.1.2Lambda表达式的综合案例-案例小结05通过本实验,学生将掌握Lambda表达式的基本语法和应用,能够使用Lambda表达式简化集合操作、事件监听和自定义函数式接口的实现。Lambda表达式不仅能提高代码的简洁性,还能提升代码的可读性和可维护性,尤其在处理大量数据和事件驱动的编程中具有广泛的应用。4.2StreamAPIStream创建通过集合、数组或I/O操作创建Stream,为后续操作提供数据源。中间操作使用filter、map、distinct等方法对Stream进行转换和过滤,实现数据处理。终端操作通过collect、forEach、reduce等方法对Stream进行汇总,完成数据分析。综合案例设计结合Stream的创建、中间操作和终端操作,设计一个具体的应用场景,如数据统计或文本分析。4.2.1StreamAPI的基础知识StreamAPI是Java8中引入的用于处理集合(collection)的功能,提供了一种声明性的方法来对数据进行过滤、映射、排序等操作。StreamAPI提供了流式操作,通过Lambda表达式进行操作,使得代码更加简洁和直观。StreamAPI的常见操作:•创建Stream:可以通过集合、数组等创建Stream。•中间操作:如filter()、map()、sorted(),这些操作不会立即执行,它们会返回一个新的Stream对象。•终端操作:如collect()、forEach()、reduce(),这些操作会触发Stream的计算。1.Stream基本操作式4.2.1StreamAPI的基础知识importjava.util.Arrays;importjava.util.List;publicclassStreamExample{publicstaticvoidmain(String[]args){List<Integer>numbers=Arrays.asList(1,2,3,4,5,6,7,8,9,10);//使用StreamAPI进行过滤、映射和求和操作intsum=numbers.stream().filter(n->n%2==0)//过滤出偶数.mapToInt(Integer::intValue)//转换为基本数据类型.sum();//求和System.out.println("Sumofevennumbers:"+sum);//输出:Sumofeven//numbers:30}}2.Stream排序与去重4.2.1StreamAPI的基础知识importjava.util.Arrays;importjava.util.List;publicclassStreamExample1{publicstaticvoidmain(String[]args){List<String>words=Arrays.asList("apple","banana","pear","apple","orange");//去重并排序words.stream().distinct()//去重.sorted()//排序.forEach(System.out::println);//输出:apple,banana,orange,pear}}3.Stream的map和reduce操作4.2.1StreamAPI的基础知识importjava.util.Arrays;importjava.util.List;publicclassStreamExample2{publicstaticvoidmain(String[]args){List<String>words=Arrays.asList("hello","world","java","stream");//将每个单词转为大写并拼接Stringresult=words.stream().map(String::toUpperCase)//转大写.reduce((s1,s2)->s1+""+s2)//拼接成一个字符串.orElse("Nowords");System.out.println(result);//输出:HELLOWORLDJAVASTREAM}}4.Stream收集操作(collect)4.2.1StreamAPI的基础知识importjava.util.Arrays;importjava.util.List;importjava.util.stream.Collectors;publicclassStreamExample3{publicstaticvoidmain(String[]args){List<String>words=Arrays.asList("apple","banana","pear","orange");//将所有单词转为大写并收集到列表List<String>upperCaseWords=words.stream().map(String::toUpperCase).collect(Collectors.toList());//收集为列表System.out.println(upperCaseWords);//输出:[APPLE,BANANA,PEAR,//ORANGE]}}4.2.2StreamAPI的综合案例01实验名称:JavaStreamAPI综合应用案例02实验目的•理解Java8中的StreamAPI及其常见操作(如过滤、映射、排序、聚合等)。•掌握StreamAPI的链式调用和延迟计算特性。•实践如何通过StreamAPI对集合数据进行复杂处理。•学会如何结合StreamAPI进行数据转换、过滤、分组、排序和收集。03实验内容•使用StreamAPI对数据进行过滤、排序、映射等操作。•通过StreamAPI进行数据分组、聚合等操作。•实现数据的并行处理,了解StreamAPI的并行流。•结合StreamAPI和自定义对象进行复杂数据操作。(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04importjava.util.*;importjava.util.stream.*;classStudent1{Stringname;intscore;Student1(Stringname,intscore){=name;this.score=score;}
publicStringgetName(){returnname;}publicintgetScore(){returnscore;}@OverridepublicStringtoString(){returnname+":"+score;}}(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04publicclassStreamBasicExample{publicstaticvoidmain(String[]args){List<Student1>students=Arrays.asList(newStudent1("Alice",85),newStudent1("Bob",72),newStudent1("Charlie",95),newStudent1("David",60),newStudent1("Eve",75));(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04//过滤出成绩大于80的学生System.out.println("成绩大于80的学生:");students.stream().filter(s->s.getScore()>80).forEach(System.out::println);(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04//对学生按照成绩进行降序排序System.out.println("\n按成绩降序排序:");students.stream().sorted((s1,s2)->Ipare(s2.getScore(),s1.getScore())).forEach(System.out::println);(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04//将学生姓名转换为大写System.out.println("\n学生姓名大写:");students.stream().map(s->s.getName().toUpperCase()).forEach(System.out::println);(1)StreamAPI基础操作:过滤、映射、排序任务描述:创建一个包含学生对象的List集合,通过StreamAPI进行数据的过滤、排序、映射和转换。操作步骤:创建一个Student类,其中包含姓名和成绩属性。使用StreamAPI进行以下操作:过滤出成绩大于80分的学生。对学生按照成绩进行降序排序。将学生姓名转换为大写。获取所有学生的姓名列表。4.2.2StreamAPI的综合案例-实验步骤04//获取所有学生的姓名列表System.out.println("\n所有学生的姓名:");List<String>names=students.stream().map(Student1::getName).collect(Collectors.toList());names.forEach(System.out::println);(2)StreamAPI聚合操作:最值、求和、平均值任务描述:通过StreamAPI对学生成绩进行聚合计算,求出学生成绩的总数、平均值和最值。操作步骤:使用StreamAPI计算学生成绩的总和、平均分、最大成绩和最小成绩。4.2.2StreamAPI的综合案例-实验步骤04importjava.util.*;importjava.util.stream.*;publicclassStreamAggregationExample{publicstaticvoidmain(String[]args){List<Student1>students=Arrays.asList(newStudent1("Alice",85),newStudent1("Bob",72),newStudent1("Charlie",95),newStudent1("David",60),newStudent1("Eve",75));(2)StreamAPI聚合操作:最值、求和、平均值任务描述:通过StreamAPI对学生成绩进行聚合计算,求出学生成绩的总数、平均值和最值。操作步骤:使用StreamAPI计算学生成绩的总和、平均分、最大成绩和最小成绩。4.2.2StreamAPI的综合案例-实验步骤04//计算学生成绩的总和inttotalScore=students.stream().mapToInt(Student1::getScore).sum();System.out.println("总成绩:"+totalScore);//计算学生成绩的平均值doubleaverageScore=students.stream().mapToInt(Student1::getScore).average().orElse(0);System.out.println("平均成绩:"+averageScore);(2)StreamAPI聚合操作:最值、求和、平均值任务描述:通过StreamAPI对学生成绩进行聚合计算,求出学生成绩的总数、平均值和最值。操作步骤:使用StreamAPI计算学生成绩的总和、平均分、最大成绩和最小成绩。4.2.2StreamAPI的综合案例-实验步骤04//获取成绩最高的学生Student1topStudent=students.stream().max(CparingInt(Student1::getScore)).orElseThrow(NoSuchElementException::new);System.out.println("成绩最高的学生:"+topStudent);//获取成绩最低的学生Student1bottomStudent=students.stream().min(CparingInt(Student1::getScore)).orElseThrow(NoSuchElementException::new);System.out.println("成绩最低的学生:"+bottomStudent);}}(3)StreamAPI分组与分区任务描述:通过StreamAPI对学生数据进行分组,按照成绩进行分组,并将成绩划分为及格和不及格两组。操作步骤:①
使用Collectors.groupingBy对学生进行分组。②
使用Collectors.partitioningBy对学生进行分区。4.2.2StreamAPI的综合案例-实验步骤04importjava.util.*;importjava.util.stream.*;publicclassStreamGroupingExample{publicstaticvoidmain(String[]args){List<Student1>students=Arrays.asList(newStudent1("Alice",85),newStudent1("Bob",72),newStudent1("Charlie",95),newStudent1("David",60),newStudent1("Eve",75));(3)StreamAPI分组与分区任务描述:通过StreamAPI对学生数据进行分组,按照成绩进行分组,并将成绩划分为及格和不及格两组。操作步骤:①
使用Collectors.groupingBy对学生进行分组。②
使用Collectors.partitioningBy对学生进行分区。4.2.2StreamAPI的综合案例-实验步骤04//按成绩进行分组Map<Integer,List<Student1>>groupedByScore=students.stream().collect(Collectors.groupingBy(Student1::getScore));System.out.println("按成绩分组:");groupedByScore.forEach((score,studentList)->{System.out.println("成绩:"+score);studentList.forEach(System.out::println);});(3)StreamAPI分组与分区任务描述:通过StreamAPI对学生数据进行分组,按照成绩进行分组,并将成绩划分为及格和不及格两组。操作步骤:①
使用Collectors.groupingBy对学生进行分组。②
使用Collectors.partitioningBy对学生进行分区。4.2.2StreamAPI的综合案例-实验步骤04//按成绩是否及格进行分区Map<Boolean,List<Student1>>partitionedByPass=students.stream().collect(Collectors.partitioningBy(s->s.getScore()>=60));System.out.println("\n及格和不及格学生分区:");partitionedByPass.forEach((isPassed,studentList)->{StringpassStatus=isPassed?"及格":"不及格";System.out.println(passStatus+"学生:");studentList.forEach(System.out::println);});}}(4)并行流操作任务描述:使用并行流对大数据进行处理,观察并行流的执行效果和性能提升。操作步骤:①
使用parallelStream来处理数据,计算所有学生的成绩总和。②
观察并行流与顺序流的执行时间差异。4.2.2StreamAPI的综合案例-实验步骤04importjava.util.*;importjava.util.stream.*;publicclassStreamParallelExample{publicstaticvoidmain(String[]args){List<Student1>students=Arrays.asList(newStudent1("Alice",85),newStudent1("Bob",72),newStudent1("Charlie",95),newStudent1("David",60),newStudent1("Eve",75));(4)并行流操作任务描述:使用并行流对大数据进行处理,观察并行流的执行效果和性能提升。操作步骤:①
使用parallelStream来处理数据,计算所有学生的成绩总和。②
观察并行流与顺序流的执行时间差异。4.2.2StreamAPI的综合案例-实验步骤04//顺序流计算总成绩longstartTime=System.currentTimeMillis();inttotalScoreSequential=students.stream().mapToInt(Student1::getScore).sum();longendTime=System.currentTimeMillis();System.out.println("顺序流计算总成绩:"+totalScoreSequential);System.out.println("顺序流执行时间:"+(endTime-startTime)+"ms");(4)并行流操作任务描述:使用并行流对大数据进行处理,观察并行流的执行效果和性能提升。操作步骤:①
使用parallelStream来处理数据,计算所有学生的成绩总和。②
观察并行流与顺序流的执行时间差异。4.2.2StreamAPI的综合案例-实验步骤04//并行流计算总成绩startTime=System.currentTimeMillis();inttotalScoreParallel=students.parallelStream().mapToInt(Student1::getScore).sum();endTime=System.currentTimeMillis();System.out.println("并行流计算总成绩:"+totalScoreParallel);System.out.println("并行流执行时间:"+(endTime-startTime)+"ms");}}4.2.2StreamAPI的综合案例--案例小结05通过本实验,学生将能够熟练掌握Java中的StreamAPI,能够灵活地使用Stream进行数据的过滤、排序、分组、聚合、映射等常见操作。通过并行流的使用,能够在多核CPU上提升数据处理的效率。StreamAPI的流式处理和链式调用方式使得代码更加简洁、高效,尤其在处理大量数据时,能够提高程序的可读性和性能。4.3Optional类Optional类方法讲解isPresent方法,判断Optional对象是否包含值,返回true或false,设计案例演示其使用场景。链接调用介绍Optional类中的flatMap方法,实现Optional对象间的链接调用,避免重复的Optional包装,案例展示其高效性。4.3.1Optional类的基础知识Optional类是Java8引入的一个容器类,用于表示可能为空的值。它是java.util包中的一个类,用于避免直接处理null值,从而减少空指针异常(NullPointerException)的风险。Optional类提供了一些有用的方法,使得在处理null值时更加安全和简洁。Optional类的常见方法:①Optional.of(value):创建一个非空的Optional对象,值不能为空。②Optional.ofNullable(value):创建一个可以为空的Optional对象。③Optional.empty():创建一个空的Optional对象。④isPresent():判断Optional是否包含非null的值。⑤ifPresent(Consumer<?superT>action):如果Optional中包含值,则执行给定的动作。⑥orElse(Tother):如果Optional中的值为空,返回指定的默认值。⑦orElseGet(Supplier<?extendsT>other):如果Optional中的值为空,使用指定的默认值。⑧orElseThrow(Supplier<?extendsX>exceptionSupplier):如果Optional中的值为空,抛出指定的异常。4.3.1Optional类的基础知识importjava.util.Optional;publicclassOptionalExample{publicstaticvoidmain(String[]args){//创建一个Optional对象Optional<String>optional=Optional.of("Hello,World!");//判断Optional是否存在值if(optional.isPresent()){System.out.println("Valueispresent:"+optional.get());//输出://Valueispresent:Hello,World!}
4.3.1Optional类的基础知识//使用ifPresent()来执行动作optional.ifPresent(value->System.out.println("Valueis:"+value));//输出:Valueis:Hello,World!//使用orElse()提供默认值StringdefaultValue=(String)Optional.ofNullable(null).orElse("DefaultValue");System.out.println(defaultValue);//输出:DefaultValue//使用orElseGet()提供默认值Stringresult=(String)Optional.ofNullable(null).orElseGet(()->"GeneratedDefault");System.out.println(result);//输出:GeneratedDefault}}4.3.2Optional类的综合案例01实验名称:JavaOptional类综合应用案例。02实验目的•理解Java8中的Optional类及其作用,避免空指针异常(NullPointerException)。•掌握Optional的常见方法,如of()、empty()、isPresent()、ifPresent()、map()、flatMap()、orElse()、orElseGet()等。•熟悉Optional的链式调用和懒加载特性。•掌握如何使用Optional进行安全的数据处理,避免手动的空值检查。03实验内容•使用Optional包装可能为空的对象,避免显式的null检查。•使用Optional链式调用和映射操作进行数据处理。•使用Optional的条件判断方法(如isPresent()、ifPresent())进行流式处理。•使用Optional的orElse()和orElseGet()方法提供默认值。(1)使用Optional避免空指针异常任务描述:使用Optional包装一个可能为null的对象,避免手动空值检查。操作步骤:创建一个User类,包含name和address属性,模拟获取用户地址信息时,可能存在为null的情况。使用Optional来包装可能为空的address对象。4.3.2Optional类的综合案例-实验步骤04importjava.util.Optional;classUser{Stringname;Stringaddress;User(Stringname,Stringaddress){=name;this.address=address;}publicStringgetAddress(){returnaddress;}}(1)使用Optional避免空指针异常任务描述:使用Optional包装一个可能为null的对象,避免手动空值检查。操作步骤:创建一个User类,包含name和address属性,模拟获取用户地址信息时,可能存在为null的情况。使用Optional来包装可能为空的address对象。4.3.2Optional类的综合案例-实验步骤04publicclassOptionalBasicExample{publicstaticvoidmain(String[]args){Useruser=newUser("Alice",null);//地址为空//使用Optional包装可能为空的addressOptional<String>addressOptional=Optional.ofNullable(user.getAddress());(1)使用Optional避免空指针异常任务描述:使用Optional包装一个可能为null的对象,避免手动空值检查。操作步骤:创建一个User类,包含name和address属性,模拟获取用户地址信息时,可能存在为null的情况。使用Optional来包装可能为空的address对象。4.3.2Optional类的综合案例-实验步骤04//使用isPresent()检查值是否存在if(addressOptional.isPresent()){System.out.println("Address:"+addressOptional.get());}else{System.out.println("Noaddressavailable");}//使用ifPresent()执行操作addressOptional.ifPresent(address->System.out.println("Address:"+address));}}(2)使用Optional的map()和flatMap()任务描述:通过Optional链式调用对用户的地址进行处理。链式调用可以避免空值检查,使代码更简洁。操作步骤:使用map()对地址字符串进行转换(如地址大写),如果address为空,则跳过该操作。使用flatMap()处理嵌套的Optional对象,避免产生多个嵌套的Optional。4.3.2Optional类的综合案例-实验步骤04importjava.util.Optional;classUser{Stringname;Stringaddress;User(Stringname,Stringaddress){=name;this.address=address;}publicOptional<String>getAddress(){returnOptional.ofNullable(address);}}(2)使用Optional的map()和flatMap()任务描述:通过Optional链式调用对用户的地址进行处理。链式调用可以避免空值检查,使代码更简洁。操作步骤:使用map()对地址字符串进行转换(如地址大写),如果address为空,则跳过该操作。使用flatMap()处理嵌套的Optional对象,避免产生多个嵌套的Optional。4.3.2Optional类的综合案例-实验步骤04publicclassOptionalMapFlatMapExample{publicstaticvoidmain(String[]args){Useruser=newUser("Alice","NewYork");//使用map()对address进行处理Optional<String>addressOptional=user.getAddress().map(address->address.toUpperCase());//将地址转换为大写addressOptional.ifPresent(address->System.out.println("ProcessedAddress:"+address));(2)使用Optional的map()和flatMap()任务描述:通过Optional链式调用对用户的地址进行处理。链式调用可以避免空值检查,使代码更简洁。操作步骤:使用map()对地址字符串进行转换(如地址大写),如果address为空,则跳过该操作。使用flatMap()处理嵌套的Optional对象,避免产生多个嵌套的Optional。4.3.2Optional类的综合案例-实验步骤04//使用flatMap()处理嵌套的OptionalOptional<Optional<String>>nestedOptional=Optional.of(user.getAddress());nestedOptional.flatMap(o->o)//将嵌套的Optional展平.ifPresent(address->System.out.println("FlatMappedAddress:"+address));}}(3)使用Optional的orElse()和orElseGet()方法提供默认值任务描述:在Optional为空时,使用orElse()和orElseGet()方法提供默认值或默认值生成逻辑。操作步骤:使用orElse()方法直接提供默认值。使用orElseGet()方法通过懒加载的方式提供默认值。4.3.2Optional类的综合案例-实验步骤04importjava.util.Optional;publicclassOptionalDefaultValueExample{publicstaticvoidmain(String[]args){Optional<String>addressOptional=Optional.ofNullable(null);//空值//使用orElse()提供默认值Stringaddress=addressOptional.orElse("UnknownAddress");System.out.println("Address(orElse):"+address);//使用orElseGet()提供默认值(通过懒加载)StringaddressLazy=addressOptional.orElseGet(()->"LazyDefaultAddress");System.out.println("Address(orElseGet):"+addressLazy);}}(4)使用Optional的filter()方法进行条件检查任务描述:使用Optional的filter()方法对值进行条件判断,只有满足特定条件时才返回Optional,否则返回空的Optional。操作步骤:使用filter()方法筛选地址中包含特定关键字的值。4.3.2Optional类的综合案例-实验步骤04importjava.util.Optional;publicclassOptionalFilterExample{publicstaticvoidmain(String[]args){Optional<String>addressOptional=Optional.ofNullable("NewYorkCity");//使用filter()检查地址是否包含"City"Optional<String>filteredAddress=addressOptional.filter(address->address.contains("City"));filteredAddress.ifPresent(address->System.out.println("FilteredAddress:"+address));}}(5)Optional结合自定义方法:处理可能为空的复杂数据任务描述:创建一个系统,模拟从数据库或外部服务获取数据时,可能返回null的情况,通过Optional简化代码。操作步骤:模拟从数据库获取用户信息的方法,并返回Optional类型。使用Optional链式调用处理可能为null的值。4.3.2Optional类的综合案例-实验步骤04importjava.util.Optional;classUser{Stringname;Stringaddress;User(Stringname,Stringaddress){=name;this.address=address;}
publicStringgetName(){returnname;}publicOptional<String>getAddress(){returnOptional.ofNullable(address);}}(5)Optional结合自定义方法:处理可能为空的复杂数据任务描述:创建一个系统,模拟从数据库或外部服务获取数据时,可能返回null的情况,通过Optional简化代码。操作步骤:模拟从数据库获取用户信息的方法,并返回Optional类型。使用Optional链式调用处理可能为null的值。4.3.2Optional类的综合案例-实验步骤04classUserService{//模拟从数据库或外部服务获取用户数据publicOptional<User>findUserById(intuserId){if(userId==1){returnOptional.of(newUser("Alice","NewYork"));}else{returnOptional.empty();//用户未找到}}}(5)Optional结合自定义方法:处理可能为空的复杂数据任务描述:创建一个系统,模拟从数据库或外部服务获取数据时,可能返回null的情况,通过Optional简化代码。操作步骤:模拟从数据库获取用户信息的方法,并返回Optional类型。使用Optional链式调用处理可能为null的值。4.3.2Optional类的综合案例-实验步骤04publicclassOptionalCustomExample{publicstaticvoidmain(String[]args){UserServiceuserService=newUserService();//使用Optional避免nullOptional<User>userOptional=userService.findUserById(1);//获取用户的地址信息,如果存在则输出,如果为空则输出默认消息Stringaddress=userOptional.flatMap(User::getAddress).orElse("Addressnotavailable");System.out.println("UserAddress:"+address);(5)Optional结合自定义方法:处理可能为空的复杂数据任务描述:创建一个系统,模拟从数据库或外部服务获取数据时,可能返回null的情况,通过Optional简化代码。操作步骤:模拟从数据库获取用户信息的方法,并返回Optional类型。使用Optional链式调用处理可能为null的值。4.3.2Optional类的综合案例-实验步骤04//查询不存在的用户,展示Optional的空值处理Optional<User>userOptional2=userService.findUserById(2);Stringaddress2=userOptional2.flatMap(User::getAddress).orElse("Addressnotavailable");System.out.println("UserAddress:"+address2);}}4.3.2Optional类的综合案例-案例小结05通过本实验,学生将掌握Optional类在Java中的应用,能够有效避免空指针异常,并提高代码的简洁性和可读性。通过Optional的各种方法(如map()、flatMap()、filter()、orElse()、orElseGet()等),学生能够更优雅地处理可能为null的值,尤其是在处理复杂数据时,避免手动的null检查,减少冗余代码。4.4Java21特性Java21特性主要讲解虚拟线程、结构化并发、模式匹配增强等内容,并且基于这些内容设计一个综合案例。1.虚拟线程虚拟线程(virtualthreads)是Java21引入的一个重大特性,它是对Java中的线程模型的重大改进。虚拟线程是轻量级的线程,可以在JVM上并行运行大量任务。它们相比于平台线程(即操作系统级线程)更加高效,并且能够显著提高I/O密集型应用的并发性能。目的:简化并发编程,特别是在高并发的I/O密集型应用中,虚拟线程大大减少了线程创建和上下文切换的开销。使用:通过java.util.concurrent包中的新API,开发者可以很容易地使用虚拟线程。4.4.1Java21特性的基础知识impo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026广告增长运营面试题及答案
- 2026国企面试题集及答案
- 2026环保专业的面试题及答案
- 2026货运电话面试题目及答案
- 2026健康部面试题目及答案
- 2026进贤小学面试题目及答案
- 客服专项面试题及答案
- 中级社工社区工作全真模拟预测题库卷含完整答案
- 2027年日照现代工程学院高职单招职业技能考试模拟试卷附参考答案详解【预热题】
- 2027年四川三河职业学院高职单招职业适应性测试考试模拟试卷带答案详解(培优)
- 2026上海复旦大学附属中山医院青浦新城院区临床护理岗位招聘笔试题库及答案详解
- 2026年广东省考《申论》真题及答案解析(县级卷)
- 2026年食品安全法知识竞赛试题及答案
- 2026年齐齐哈尔拜泉县公开招聘幼儿教师34人笔试备考试题及答案详解
- 2026年浙江省宁波市初一新生入学分班数学考试真题及答案
- 肿瘤靶向治疗药物皮肤不良反应防治专家共识
- 医院担架外包合同
- 中国溃疡性结肠炎诊治指南2023年课件
- 《工业管道安全技术规程》(TSG31-2025)监督检验规则培训
- 施工人员安全教育与培训方案
- 勘察单位质量安全管理制度(3篇)
评论
0/150
提交评论