面向对象技术与方法JAVA 实验--上(Easy)

面向对象技术与方法(JAVA)


  关键词:面向对象JAVA、方法重写、Lambda表达式、文件类、输入输出流


背景信息


  这是2022年春季学期,北京理工大学,计算机学院,软件工程,开设的一门必修课程,为期八周,共32课时,难度较大,教师课件使用英文讲授,自学的收获更多。

  成绩主要分为三部分,作业、实验、考试。本篇内容为实验题,共六个大题,其中两道难度非常高,以当时的水平写出来实属不易。其他题目更多的是了解面向对象语言的特点和语法。

  本篇内容是实验题中的难题。


2022面向对象JAVA实验

目录

 (点击跳转)

  1. equals方法重写
  2. Lambda表达式排序
  3. 文件与输入输出流
  4. 综合编程题



一、equals()方法重写

  实现一个名为Value 的类,其中含有一个字符类型的成员x 和双精度类型的成员y。请重写(override)其equals( )方法,使得用equals( )比较Value 类的两个对象的内容时,相等条件是对象的所有成员分别对应相等。

思路

  首先创建Value类,成员有char x,double y以及相应的构造器初始化,重写equals方法,将原先的比较地址改为数据成员的比较,相等返回true,不等返回false。在main方法中创建三个对象,并调用构造器初始化,调用equals方法检验结果。

收获

       此题涉及三个知识点:输入、输出和数组排序。输入和输出比较相似,这一题中更多注意输出的时候,考虑到要进行后续的读取,因此选用DataInputStream而不是PrintWriter,并且对于将字符写入文件应当更多使用writeBytes而不是writeChar(后者更容易出错)。对于排序有两种思路,一种是直接集成Comparable接口,实现其中的campareTo方法,按照需要确定大于(1)、等于(0)和小于(-1)。使用时直接使用Arrays.sort进行排序。还有一种是新建一个实现Comparator接口的类作为比较器,实现其中的campare方法(与上述相同)。使用时在Arrays.sort中加入该类作为比较器。

源码

package java_exp2022;

class Value{
	char x;
	double y;
	Value(char x,double y){
		this.x = x;
		this.y = y;
	}
	boolean equals(Value v1) {
		if( v1.x == this.x && v1.y == this.y) return true;
		else return false;
	}
}
public class Project1 {
	public static void main(String[] args) {
		Value a = new Value('a',2.33);
		Value b = new Value('b',3.22);
		Value c = new Value('a',2.33);
		System.out.println("Does value_a equal to value_b?\n"+a.equals(b));
		System.out.println("Does value_a equal to value_c?\n"+a.equals(c));
		System.out.println("Does value_b equal to value_c?\n"+b.equals(c));
	}
}
/*OutPut
Does value_a equal to value_b?
false
Does value_a equal to value_c?
true
Does value_b equal to value_c?
false
*/



二、Lambda表达式排序


  使用Lambda表达式比较器Comparator给List对象排序,分别按Name、Age(倒序)、Grade排序。List对象内容如下表:

IDNameAgeGrade
1ZhangSan2898
2LiSi21100
3KangKang2789
4LiMing1992
5WangGang2266
6ZhaoXin2485
7LiuWei2078
8BaiZhanTang1699

思路

  首先创立基本的对象Student,包含数据成员Integer ID,age,grade和String name,为了后面方便直接调用比较器比较,这里使用了对象类型的Integer,还是使用构造器进行初始化。在main函数中使用ArrayList容纳Student类;调用add方法添加对象,继续调用sort方法,方法中写入lambda表达式( Student st1 , Student st2 ) -> st1.ID.compareTo(st2.ID),将list中的成员按照ID的从小到大排序;其他排序完全类似。

收获

  这个题目涉及的知识点有:容器类的使用,数据的排序,lambda表达式,数据的输出。先创立基本的对象Student,使用ArrayList容纳Student类;调用sort方法,方法中写入lambda表达式( Student st1 , Student st2 ) -> st1.ID.compareTo(st2.ID),即可完成前类的容纳,排序,lambda表达式的使用;最后在main方法之外,即Project2(实验二)类中添加一个static修饰的printlist方法,使用static修饰可以不用再创建类直接调用方法,在方法中建立迭代器Iterator it = list.iterator();继而实现对Student的数据成员逐个打印,即可查看排序效果。

源码

package java_exp2022;
import java.util.*;

class Student{
	Integer ID,age,grade;
	String name;
	Student(Integer _ID,Integer _age,Integer _grade,String _name){
		ID = _ID;
		age = _age;
		grade = _grade;
		name = _name;
	}
}
public class Project2 {
	static void printlist(ArrayList<Student> list) {
		Iterator<Student> it = list.iterator();
		while(it.hasNext()) {
			Student st = it.next(); 
			System.out.println("ID = "+st.ID+" , Age = "+st.age+" ,
							 Grade = "+st.grade+" , Name = "+st.name);
		}
	}
	public static void main(String[] args) {
		ArrayList<Student> list = new ArrayList<Student>(); 
		list.add(new Student(1,28,98,"ZhangSan"));
		list.add(new Student(2,21,100,"LiSi"));
		list.add(new Student(3,27,89,"KangKang"));
		list.add(new Student(4,19,92,"LiMing"));
		list.add(new Student(5,22,66,"WangGang"));
		list.add(new Student(6,24,85,"ZhaoXin"));
		list.add(new Student(7,20,78,"LiuWei"));
		list.add(new Student(8,16,99,"BaiZhanTang"));
		list.sort( ( Student st1 , Student st2 ) -> st1.ID.compareTo(st2.ID) );
		System.out.println("------Sorted by ID-----");
		printlist(list);
		list.sort( ( Student st1 , Student st2 ) -> st2.age.compareTo(st1.age) );
		System.out.println("------Sorted by Age(down)-----");
		printlist(list);
		list.sort( ( Student st1 , Student st2 ) -> st1.grade.compareTo(st2.grade) );
		System.out.println("------Sorted by Grade-----");
		printlist(list);
		list.sort( ( Student st1 , Student st2 ) -> st1.name.compareTo(st2.name) );
		System.out.println("------Sorted by Name-----");
		printlist(list);
	}
}
/*OutPut
------Sorted by ID-----
ID = 1 , Age = 28 , Grade = 98 , Name = ZhangSan
ID = 2 , Age = 21 , Grade = 100 , Name = LiSi
ID = 3 , Age = 27 , Grade = 89 , Name = KangKang
ID = 4 , Age = 19 , Grade = 92 , Name = LiMing
ID = 5 , Age = 22 , Grade = 66 , Name = WangGang
ID = 6 , Age = 24 , Grade = 85 , Name = ZhaoXin
ID = 7 , Age = 20 , Grade = 78 , Name = LiuWei
ID = 8 , Age = 16 , Grade = 99 , Name = BaiZhanTang
------Sorted by Age(down)-----
ID = 1 , Age = 28 , Grade = 98 , Name = ZhangSan
ID = 3 , Age = 27 , Grade = 89 , Name = KangKang
ID = 6 , Age = 24 , Grade = 85 , Name = ZhaoXin
ID = 5 , Age = 22 , Grade = 66 , Name = WangGang
ID = 2 , Age = 21 , Grade = 100 , Name = LiSi
ID = 7 , Age = 20 , Grade = 78 , Name = LiuWei
ID = 4 , Age = 19 , Grade = 92 , Name = LiMing
ID = 8 , Age = 16 , Grade = 99 , Name = BaiZhanTang
------Sorted by Grade-----
ID = 5 , Age = 22 , Grade = 66 , Name = WangGang
ID = 7 , Age = 20 , Grade = 78 , Name = LiuWei
ID = 6 , Age = 24 , Grade = 85 , Name = ZhaoXin
ID = 3 , Age = 27 , Grade = 89 , Name = KangKang
ID = 4 , Age = 19 , Grade = 92 , Name = LiMing
ID = 1 , Age = 28 , Grade = 98 , Name = ZhangSan
ID = 8 , Age = 16 , Grade = 99 , Name = BaiZhanTang
ID = 2 , Age = 21 , Grade = 100 , Name = LiSi
------Sorted by Name-----
ID = 8 , Age = 16 , Grade = 99 , Name = BaiZhanTang
ID = 3 , Age = 27 , Grade = 89 , Name = KangKang
ID = 4 , Age = 19 , Grade = 92 , Name = LiMing
ID = 2 , Age = 21 , Grade = 100 , Name = LiSi
ID = 7 , Age = 20 , Grade = 78 , Name = LiuWei
ID = 5 , Age = 22 , Grade = 66 , Name = WangGang
ID = 1 , Age = 28 , Grade = 98 , Name = ZhangSan
ID = 6 , Age = 24 , Grade = 85 , Name = ZhaoXin
*/



三、文件与输入输出流


  打开中的lunch.java文件,一次读取其中的一行,令每行形成一个String对象。然后利用java.util.Comparator接口重新定义String对象间的比较方法:将每个String中的小写字母转为大写后再进行比较。使用该比较法对这些String进行排序,按从大到小的顺序存入一个LinkedList。最后将LinkedList中的String按存入的相反顺序输出到另一个文件inverse.txt中。

  lunch.java文件如下图所示:

文本读取的目标文件

思路

  首先利用java.util.Comparator接口重新定义String对象间的比较方法,由于实现接口不能降低方法的可视性,在新的方法中仍然使用public修饰,返回值为了两个String类型都转化为大写,即调用toUpperCase方法,继而调用campareTo方法比较两个字符串;接着读入文件的数据,因为要按行处理,因此使用BufferedReader读入,继而使用ArrayList容纳每一行的字符串,并用try catch块包裹;后面使用foreach语句打印至控制台查看读取效果,使用题目2的排序方法,对list中的字符串按要求排序,最后写入文件即可。

收获

  这个题目涉及的知识点有:接口的实现,文件的读取与写入,字符串的大小写转换,字符串的排序。首先利用java.util.Comparator接口重新定义String对象间的比较方法,调用toUpperCase方法转化为大写,继而调用campareTo方法比较两个字符串;接着使用BufferedReader按行读入文件数据,使用ArrayList容纳,;使用foreach语句打印至控制台便于查看,建立比较器,使用lambda语句将list内容按要求排序,使用FileWriter类,调用.write方法将排序好的数据写入目标文件。

源码

package java_exp2022;
import java.io.*;
import java.util.*;

class ComparatorNew implements Comparator<String>{
	public int compare(String o1, String o2) {
		return o1.toUpperCase().compareTo(o2.toUpperCase());
	}
}
public class Project3 {
	public static void main(String[] args) {
		System.out.println("请将lunch.java文件放置于D://javatest//"
				+ "\n最终的inverse.txt文件也为存于此目录下");
		File f = new File("D://javatest//lunch.java");
		File f_wr = new File("D://javatest//inverse.txt");
		try {
			BufferedReader br = new BufferedReader(new FileReader(f));
			ArrayList<String> str = new ArrayList<String>();
			String temp = null;
			while( (temp = br.readLine() ) != null )
			str.add(temp);
			System.out.println("--------before-------");
			for(String s : str)
				System.out.println(s);
			ComparatorNew com = new ComparatorNew();
			str.sort( (String s1,String s2) -> com.compare(s1,s2));
			LinkedList<String> l_str = new LinkedList<String>();
			System.out.println("--------sorted-------");
			for(String s : str) {
				l_str.add(s);
				System.out.println(s);
			}
			int num = l_str.size();
			FileWriter wr = new FileWriter(f_wr);
			f_wr.createNewFile();
			System.out.println("--------turn around-------");
			for(int i = num-1 ; i>=0 ; i--) {
			    System.out.println(l_str.get(i));
			    wr.write(l_str.get(i)+"\n");
			}
			wr.close();
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

输出结果

输出结果


四、综合编程题


  一个图书管理系统的面向对象设计方案如下图所示:结构图

  Book代表书,有”Name(书名)“、“Author(作者)”、”Price(价格)“、”IsBorrowed(是否借出)”四个属性。类Library代表图书馆,其内部字段books用于保存图书馆中所有的书,他的FindBook()方法依据书名查找同名的书(可能有多本)。另一个Get AllBooks()方法获取馆藏所有书的详细信息。类Reader代表作者,Name字段代表其姓名,读者可以进行BorrowBook()(借书),ReturnBook():(还书)操作。

请完成以下工作:

  1. 用Java编程实现以上三个类。
  2. 在main()方法内书写以下测试代码:
    (1) 创建一个Library的类的实例,myLittleLibrary,其中预存有以下三本书:
      Java程序设计,张三著,45元
      Java核心设计,李四著,50元
      Java程序设计,王五著,38元
    (2) 显示图书馆所有图书的信息,输出样例如下:
      Java程序设计,张三著,45元,可借
      Java核心设计,李四著,50元,可借
      Java程序设计,王五著,38元,未还
    (3) 创建一个Reader类的实例oneBeautifulGril,她先在myLittleLibrary中查找《Java程序设计》;
    (4) 当oneBeautifulGril借了张三著的那一本书时,显示图书馆所有图书的信息;
    (5) oneBeautifulGril把书还了,再次显示图书馆中图书信息;

思路

  我们需要建立一个Library类,类中有一个ArrayList成员,用于存储所有图书的信息和借出状态,还包含FindBook方法,GetAllBooks方法。Book类包含书名、作者、价格、借出状态。Reader类包含名字、借书方法,还书方法。主要使用了构造器初始化,foreach遍历方法等。
  我还额外考虑了题目之外的借书失败,还书错误等情况。

源码

package java_exp2022;
import java.util.*;

class Book{
	String Name;
	String Author;
	int Price;
	boolean IsBorrowed = false ; 
	Book(String _Name,String _Author,int _Price){
		Name = _Name;
		Author = _Author;
		Price = _Price;
	}
}
class Reader{
	String Name;
	Reader(String name){
		Name = name ;
	}
	void BorrowBook(Library lib,String bookname,String authorname) {
		boolean Ifsuccess = false ;
		for(Book b : lib.books) {
			Ifsuccess = false ;
			if(b.Name == bookname && b.Author == authorname && !b.IsBorrowed) {
				b.IsBorrowed = true ;
				Ifsuccess = true ;
				break;//借到就退出
			}
		}
		if(Ifsuccess) System.out.println(this.Name+" 成功借出 "+bookname+authorname+"著");
		else System.out.println(this.Name+" 借书失败 ,没有书目"+bookname+authorname+"著");
	}
    void ReturnBook(Library lib,String bookname,String authorname) {
    	boolean Ifsuccess = false ;
		for(Book b : lib.books) {
			Ifsuccess = false ;
			if(b.Name == bookname && b.Author == authorname && b.IsBorrowed) {
				b.IsBorrowed = false ;
				Ifsuccess = true ;
				break;//还完就退出
			}
		}
		if(Ifsuccess) System.out.println(this.Name+" 成功还书 "+bookname+authorname+"著");
		else System.out.println(this.Name+" 还书失败 ,"+bookname+authorname+"著 不是我们图书馆的");
	}
}
class Library{
	ArrayList<Book> books = new ArrayList<Book>();
	void FindBook(String bookname) {
		boolean Ifcontain = false ;
		System.out.println("图书"+bookname+"查找结果如下:");
		for(Book b : books) {
			if(b.Name != bookname)
				continue;//不是目标图书继续检索
			Ifcontain = true ;
			String status = null;
			if(b.IsBorrowed) status = "未还";
			else status = "可借";
			System.out.print(b.Name+", "+b.Author
					+"著, "+b.Price+"元, "+status+"\n");
		}
		if(!Ifcontain)System.out.println("查无此书");
	}//获得特定书名的书,可能会有重名书
	void GetAllBooks() {
		System.out.println("图书馆所有图书的信息如下:");
		for(Book b : books) {
			String status = null;
			if(b.IsBorrowed) status = "未还";
			else             status = "可借";
			System.out.print(b.Name+", "+b.Author
					+"著, "+b.Price+"元, "+status+"\n");
		}
	}

}
public class Project6 {
	public static void main(String[] args) {
		Library myLittleLibrary = new Library();
		myLittleLibrary.books.add(new Book("《Java程序设计》","张三",45) );
		myLittleLibrary.books.add(new Book("《Java核心设计》","李四",50) );
		myLittleLibrary.books.add(new Book("《Java程序设计》","王五",38) );
		myLittleLibrary.GetAllBooks();
		
		Reader oneBeautifulGril = new Reader("oneBeautifulGril");
		myLittleLibrary.FindBook("《Java程序设计》");
		oneBeautifulGril.BorrowBook(myLittleLibrary, "《Java程序设计》", "张三");
		myLittleLibrary.GetAllBooks();
		
		oneBeautifulGril.ReturnBook(myLittleLibrary, "《Java程序设计》", "张三");
		myLittleLibrary.GetAllBooks();
		
		System.out.println("\n以下内容为出错示例");
		myLittleLibrary.FindBook("《错误书名示例》");
		oneBeautifulGril.BorrowBook(myLittleLibrary, "《错误书名示例》", "小明");
		oneBeautifulGril.ReturnBook(myLittleLibrary, "《错误书名示例》", "小明");
	}
}
/*OutPut
图书馆所有图书的信息如下:
《Java程序设计》, 张三著, 45元, 可借
《Java核心设计》, 李四著, 50元, 可借
《Java程序设计》, 王五著, 38元, 可借
图书《Java程序设计》查找结果如下:
《Java程序设计》, 张三著, 45元, 可借
《Java程序设计》, 王五著, 38元, 可借
oneBeautifulGril 成功借出 《Java程序设计》张三著
图书馆所有图书的信息如下:
《Java程序设计》, 张三著, 45元, 未还
《Java核心设计》, 李四著, 50元, 可借
《Java程序设计》, 王五著, 38元, 可借
oneBeautifulGril 成功还书 《Java程序设计》张三著
图书馆所有图书的信息如下:
《Java程序设计》, 张三著, 45元, 可借
《Java核心设计》, 李四著, 50元, 可借
《Java程序设计》, 王五著, 38元, 可借

以下内容为出错示例
图书《错误书名示例》查找结果如下:
查无此书
oneBeautifulGril 借书失败 ,没有书目《错误书名示例》小明著
oneBeautifulGril 还书失败 ,《错误书名示例》小明著 不是我们图书馆的
*/
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值