目录
2023.6.25 编辑
增加了目录
一、实验目的
1.掌握Optional对空引用的基本操作方法
2.掌握整合集合Stream与Optional的操作方法
二、实验内容
初始化
理解实验的目的,不要浪费时间在初始化的代码,直接复制使用
java-course/java-experiments at master · bwhyman/java-course · GitHubhttps://github.com/bwhyman/java-course/tree/master/java-experimentsjava-course/java-experiments at master · bwhyman/java-course · GitHub
在com.experiment05.entity下,创建Student/Teacher/College类,直接从github复制使用实验代码
Student类
package com.experiment05.entity;
public class Student {
private int number;
private String name;
private int year;
private Teacher teacher;
public Student(int number, String name, int year) {
this.number = number;
this.name = name;
this.year = year;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
Teacher类
package com.experiment05.entity;
public class Teacher {
private int number;
private String name;
private College college;
public Teacher(int number, String name) {
this.number = number;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public College getCollege() {
return college;
}
public void setCollege(College college) {
this.college = college;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
College类
package com.experiment05.entity;
public class College {
private String name;
public College(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在com.experiment05.resource下,创建DatabaseUtils类,直接从github复制使用实验代码
DatabaseUtils类
package com.experiment05.resource;
import com.experiment05.entity.College;
import com.experiment05.entity.Student;
import com.experiment05.entity.Teacher;
import java.util.*;
public class DatabaseUtils {
private static final List<Student> STUDENTS = create();
private static List<Student> create() {
College c1 = new College("信息学院");
College c2 = new College("经济管理学院");
Teacher t1 = new Teacher(1001, "吕惠玲");
t1.setCollege(c1);
Teacher t2 = new Teacher(1002, "曾志优");
t2.setCollege(c2);
Student s1 = new Student(201001,"赵阳阳", 2010);
s1.setTeacher(t1);
Student s2 = new Student(201002,"邵鹏", 2010);
s2.setTeacher(t1);
Student s3 = new Student(201103,"高学斌", 2011);
s3.setTeacher(t2);
Student s4 = new Student(201104,"张扬", 2011);
s4.setTeacher(t2);
/**
* 原代码使用 return List.of(s1,s2, s3, s4)作为返回值
* 此时提示The method of(Student, Student, Student, Student) is undefined for the type List
* 猜测原因为Java版本不同,该方法为Java9引入
*/
//故改为以下代码:
List<Student> s=new ArrayList<>();
s.add(s1);s.add(s2);s.add(s3);s.add(s4);
return s;
}
public static List<Student> listStudents() {
return STUDENTS;
}
}
基于Optional,按需求实现测试类Test中的方法,模拟正确/错误数据信息验证代码的有效性
Test类
package com.experiment05;
import com.experiment05.entity.College;
import com.experiment05.entity.Student;
import com.experiment05.entity.Teacher;
import com.experiment05.resource.DatabaseUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public class Test {
public static void main(String[] args) {
output();
System.out.println("\n基于给定学生,获取学生的导师的所在学院名称:");
System.out.println(getCollegeName(DatabaseUtils.listStudents().get(0)));
System.out.println("\n基于给定学生及教师姓名,判断是否为给定学生的指导教师:");
System.out.println(isTeacher(DatabaseUtils.listStudents().get(0), "曾志优"));
System.out.println("\n基于给定学生集合,学生编号,实现获取学生的导师的所在学院名称:");
System.out.println(getCollegeName(DatabaseUtils.listStudents(),8888));
System.out.println("\n实现在给定学生集合中查询指定编号学生,如果学生导师编号为指定编号,打印显式导师所在学院名称:");
printCollegeName(DatabaseUtils.listStudents(), 201001, 1002);
}
/**
* 输出默认数据
*/
private static void output() {
List<Student> list=DatabaseUtils.listStudents();
System.out.println("学生:");
for(Student i:list)
System.out.println(i.getNumber()+" "+i.getName()+" "+i.getYear()+" "+i.getTeacher().getName());
System.out.println("导师:");
for(Student i:list)
System.out.println(i.getTeacher().getNumber()+" "+i.getTeacher().getName());
System.out.println("学院:");
for(Student i:list)
System.out.println(i.getTeacher().getCollege().getName());
}
/**
* 基于给定学生,获取学生的导师的所在学院名称。
* 任何一项不存在或失败,返回 未知学院
* @param student
* @return
*/
private static String getCollegeName(Student student) {
List<Student> list=DatabaseUtils.listStudents();
return list.stream()
.filter(s->s.getTeacher().equals(student.getTeacher()))
.findFirst()
.map(Student::getTeacher)
.map(Teacher::getCollege)
.map(College::getName)
.orElse("未知学院");
}
/**
* 基于给定学生及教师姓名,判断是否为给定学生的指导教师。
* 不匹配或不存在,均返回false
* @param student
* @param teacherName
* @return
*/
private static boolean isTeacher(Student student, String teacherName) {
List<Student> list=DatabaseUtils.listStudents();
if(list.stream()
.filter(s->s.getName().equals(student.getName()))
.filter(s->s.getTeacher().getName().equals(teacherName))!=null)
return false;
return true;
}
/**
* 基于给定学生集合,学生编号,实现获取学生的导师的所在学院名称。
* 任何一项不存在或失败,返回 未知学院
* 结合collection stream findFirst()方法实现
* 可直接通过一条方法链实现
*
* @param students
* @param sNumber
* @return
*/
private static String getCollegeName(List<Student> students, int sNumber) {
return students.stream()
.filter(s->s.getNumber()==sNumber)
.findFirst()
.map(Student::getTeacher)
.map(t->t.getCollege())
.map(c->c.getName())
.orElse("未知学院");
}
/**
* 实现在给定学生集合中查询指定编号学生,如果学生导师编号为指定编号,打印显式导师所在学院名称。
* 任何一项不存在或失败,打印显式 未知学院
* 结合collection stream findFirst()方法实现
* 可直接通过一条方法链实现
*
* @param students
* @param sNumber,学生编号
* @param tNumber,教师编号
*/
private static void printCollegeName(List<Student> students, int sNumber, int tNumber) {
System.out.println(students.stream()
.filter(s->s.getNumber()==sNumber)
.filter(s->s.getTeacher().getNumber()==tNumber)
.findFirst()
.map(Student::getTeacher)
.map(t->t.getCollege())
.map(c->c.getName())
.orElse("未知学院"));
}
}
结果
问题
输出默认数据的output方法为个人额外添加。而此处存在问题,输出结果中老师和学校都输出了两遍。
原因在于两个for循环都以list,即学生数据为对象遍历,每遍历一条学生数据,就会输出该学生对应的老师数据。同理,每遍历一条学生数据,就会输出该学生对应的导师的学院信息。
至于解决方法,可以考虑采用循环删除重复数据,或建立set集合存储符合条件的数据,此处不在赘述。