-->

signed

QiShunwang

“诚信为本、客户至上”

Java笔记01 Scanner.close()、InputStream、PTA(8 实验8 计算机类 (100 分))

2021/6/9 0:54:37   来源:

其实之前就有遇到过Scanner实例化的对象调用close出现一些问题,现在可能暴露了出来。
为什么是说“可能”因为我这篇博客也没给出完整的错误分析,就当挖个坑吧…

文章目录

  • 题目
  • 过关代码
  • 好了,只想要过关的童鞋可以省略以下内容了。
  • 错误笔记
    • 有问题的代码(有错误)
    • 错误简短描述
  • 分析过程
    • 错误简单分析

题目

8 实验8 计算机类 (100 分)

构造计算机类,其中包含其配置信息:处理器、主板、内存、显示器、硬盘等设备,各个设备均有型号(字符串),特别的,处理器有主频(小数)和内核数(整数)、显示器有尺寸(整型)、内存和硬盘有容量数据(GB为单位)。请你尝试构造合适的类和类的关系来表示计算机,并为该计算机类添加计算价格(各设备价格之和)、打印配置信息等方法。重写相关类的equals方法,使得两个配置完全相同的计算机为相同的计算机。重写相关类的toString函数,打印计算机的配置信息。 在main函数中

提示: 为计算机类和各个组成配件都构造类,分别重写toString和equals方法 在计算机类中调用各个配件的equals和toString方法 回车用\n 小数用String.format("%.1f",1.234)
输入格式:

两个计算机对象,包含 CPU:型号、主频、内核 主板:型号 内存:容量 显示器:尺寸 硬盘:容量
输出格式:

两个对象是否相等 两个对象的配置信息
输入样例:

在这里给出一组输入。例如:

Corei7 2.8 4
GIGABYTE-B250M-D3H
xiede-DDR3 8
SamsungC27F39 27
SEAGATE-ST1000DM010 2048
Corei7 2.8 4
GIGABYTE-B250M-D3H
xiede-DDR3 8
SamsungC27F39 27
SEAGATE-ST1000DM010 2048

输出样例:

在这里给出相应的输出。例如:

true
Computer1:
CPU:
Model: Corei7
Frequency: 2.8
Number of Cores: 4
Mainboard:
Model: GIGABYTE-B250M-D3H
Memory:
Model: xiede-DDR3
Size: 8
Screen:
Model: SamsungC27F39
Size: 27
Harddisk:
Model: SEAGATE-ST1000DM010
Size: 2048
Computer2:
CPU:
Model: Corei7
Frequency: 2.8
Number of Cores: 4
Mainboard:
Model: GIGABYTE-B250M-D3H
Memory:
Model: xiede-DDR3
Size: 8
Screen:
Model: SamsungC27F39
Size: 27
Harddisk:
Model: SEAGATE-ST1000DM010
Size: 2048

过关代码

import java.util.Scanner;

class Disk{
	String model ;
	int size;

	public Disk(){
		this.init();
	}

	public Disk(String model , int size ){
		this.model = model;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Harddisk:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}
}

class Display{
	String model ;
	int size;

	public Display(){
		this.init();
	}

	public Display(String model , int size){
		this.model = model;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Screen:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}
}

class RAM{
	String model ;
	int size;

	public RAM(){
		this.init();
	}

	public RAM(String model,int size ){
		this.model = model ;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Memory:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}

}

class MotherBoard{
	String model ;

	public MotherBoard(){
		this.init();
	}
	public MotherBoard(String model){
		this.model = model;
	}

	private void init(){
		this.model = "";
	}

	public String printInfo(){
		return "Mainboard:\nModel: " + this.model + "\n" ;
	}

}

class CPU{
	String model ;
	double clockSpeed;
	int coreCount;

	public CPU(){
		this.init();
	}

	public CPU(String model, double cS,int cC){
		this.model = model;
		this.clockSpeed = cS;
		this.coreCount = cC;
	}

	private void init(){
		this.model = "";
		this.clockSpeed = 0.0;
		this.coreCount = 0;
	}
	public String printInfo(){
		return "CPU:\nModel: " + this.model +
			"\nFrequency: " + this.clockSpeed +
			"\nNumber of Cores: " + this.coreCount + "\n" ;
	}
}

class Computer{
	String info ;
	CPU cpu;
	MotherBoard motherboard;
	RAM ram;
	Display display;
	Disk disk;


	
	public Computer(Scanner in){
		

		this.info = "";
		this.cpu = new CPU(in.next(), in.nextDouble(), in.nextInt());
		this.motherboard = new MotherBoard(in.next() );
		this.ram = new RAM(in.next(), in.nextInt());
		this.display = new Display(in.next(), in.nextInt() );
		this.disk = new Disk(in.next(), in.nextInt() );


	}

	@Override
	public String toString(){
		return  cpu.printInfo() +
				motherboard.printInfo() +
				ram.printInfo() +
				display.printInfo() +
				disk.printInfo();
	}



	@Override
	public boolean equals(Object ob){
		if( (ob == null) || !(ob instanceof Computer) ){
			return false;		
		}
		return ( this.toString().equals(ob.toString()) );
	}
}

public class Main{
	public static void main(String []arg){

		Scanner in = new Scanner(System.in);
		Computer c1 = new Computer(in),
				 c2 = new Computer(in);


		System.out.println( c1.equals(c2) );	
		System.out.println("Computer1:");	 
		System.out.print( c1.toString());
		System.out.println("Computer2:");	 
		System.out.print( c2.toString() );
	}
}

好了,只想要过关的童鞋可以省略以下内容了。

E.N.D

错误笔记

有问题的代码(有错误)

import java.util.Scanner;

class Disk{
	String model ;
	int size;

	public Disk(){
		this.init();
	}

	public Disk(String model , int size ){
		this.model = model;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Harddisk:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}
}

class Display{
	String model ;
	int size;

	public Display(){
		this.init();
	}

	public Display(String model , int size){
		this.model = model;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Screen:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}
}

class RAM{
	String model ;
	int size;

	public RAM(){
		this.init();
	}

	public RAM(String model,int size ){
		this.model = model ;
		this.size = size;
	}

	private void init(){
		this.model = "";
		this.size = 0;
	}

	public String printInfo(){
		return "Memory:\nModel: " + this.model +
			   "\nSize: " + this.size + "\n" ;
	}

}

class MotherBoard{
	String model ;

	public MotherBoard(){
		this.init();
	}
	public MotherBoard(String model){
		this.model = model;
	}

	private void init(){
		this.model = "";
	}

	public String printInfo(){
		return "Mainboard:\nModel: " + this.model + "\n" ;
	}

}

class CPU{
	String model ;
	double clockSpeed;
	int coreCount;

	public CPU(){
		this.init();
	}

	public CPU(String model, double cS,int cC){
		this.model = model;
		this.clockSpeed = cS;
		this.coreCount = cC;
	}

	private void init(){
		this.model = "";
		this.clockSpeed = 0.0;
		this.coreCount = 0;
	}
	public String printInfo(){
		return "CPU:\nModel: " + this.model +
			"\nFrequency: " + this.clockSpeed +
			"\nNumber of Cores: " + this.coreCount + "\n" ;
	}
}

class Computer{
	String info ;
	CPU cpu;
	MotherBoard motherboard;
	RAM ram;
	Display display;
	Disk disk;


	private void init(){
		Scanner in = new Scanner(System.in);

		this.info = "";
		this.cpu = new CPU(in.next(), in.nextDouble(), in.nextInt());
		this.motherboard = new MotherBoard(in.next() );
		this.ram = new RAM(in.next(), in.nextInt());
		this.display = new Display(in.next(), in.nextInt() );
		this.disk = new Disk(in.next(), in.nextInt() );
	}
	public Computer(){
		this.init();

	}

	@Override
	public String toString(){
		return  cpu.printInfo() +
				motherboard.printInfo() +
				ram.printInfo() +
				display.printInfo() +
				disk.printInfo();
	}

	@Override
	public boolean equals(Object ob){
		if( (ob == null) || !(ob instanceof Computer) ){
			return false;		
		}
		return ( this.toString().equals(ob.toString()) );
	}

	public String printPrice(){
		return "free!";
	}
}

public class Main{
	public static void main(String []arg){
		Computer c1 = new Computer(),
				 c2 = new Computer();

		System.out.println( c1.equals(c2) );
		System.out.println("Computer1:");
		System.out.print(c1.toString());

		System.out.println("Computer2:");
		System.out.print(c2.toString());
	}

}

错误简短描述

测试样例包含两个电脑,自然含有两套数据
运行程序时,分开复制黏贴(也就是一套数据一套数据地输入)可以出现预计结果;
但是,如果是两套数据一起复制黏贴(也就是十行数据一起粘)会继续等待输入,而继续输入后会抛出java.util.InputMismatchException(输入不匹配异常)

分析过程

首先的首先把范围锁定在构造方法里的scanner上;
首先猜测输入终止条件,即换行符、空格等等;
再猜测是否有中文全角或者网页复制连带格式字符干扰;
都否决后,开始分析代码逻辑。

就有了以下猜测:
一组有效数据对应一组期待输入,可以得到一组有效输出;
但两组有效数据合并对应两组期待输入,只能得到一组期望输出;

现在需要证明猜测,即让错误显式地表达出来。
方法:new一个对象,输出一次这个对象的info;再new另一个对象,输出另一个的info

错误简单分析

我归纳了一下,错误的表现为:
一组有效数据对应一组期待输入,可以得到一组有效输出;
但两组有效数据合并对应两组期待输入,只能得到一组期望输出;
可能的错误及错误原因:
第一:输入数据时,对于inputstream类或者scanner类,其中一个或两个类的实现应该是一次性的读入,不管用不用的上,用不上的数据就丢了,这就解释了当第二个期待输入时,程序得不到有效输入,因为已经被丢了。
第二:由于今天白天讨论的scanner问题,把scanner实例化在构造方法里并不合适,因为构造方法会被调用很多次。所以解决方法是,把scanner作为参数导入构造方法使用,这样就保证了scanner的唯一性。