吉林大学Java编程上机题(Lab3)


Lab3_1

题目:Enter a number of integers to the end mark 999, then sum them up. During input, non-integer input is automatically ignored. Tip: Use nextInt() method of Scanner to convert input to integer. If the input is non-integer, the method will throw an exception named InputMismatchException, which is packed in the java.util package.
Please submit program code and the screenshot of the program output in the answer.

分析
题目意思即为:
输入若干个整数,求其和,直到结束标志999为止。在输入过程中,其输入非正整数,则忽略。注意:使用nextInt()方法将输入转换为整数。如果输入是非整数,则该方法将抛出一个名为“InputMismatchException”的异常,该异常已包装在 java.util 包中。(其实也就是跳过发生InputMismatchException异常的错误输入)

首先要完成主功能:
①记录输入数据
②输入数据转换为int类型
③如果是非整数类型要抛出异常
④将输入流中的当前数据加入sum进行统计
⑤输出sum

这道题里面值得注意的就是:
使用Scanner输入流时,如果做了异常处理,nextInt输入有误抛出异常时,循环在次输入会出现无限循环抛出异常,直至栈溢出,程序崩掉。

这是由于我们键盘输入会先存储到内存的输入流区域,然后scanner对象进行数据提取并实例化,java程序通过实例化对象处理数据,但是输入流的数据发生错误没有实时剔除的话,就会使程序相关的判断陷入死循环一直异常抛出。也就是说Scanner在接受键盘输入时,会出现两种情况:
①键盘信息输入内存的信息与程序员定义的理想输入类型匹配,程序正常运转。
②不匹配,则抛出异常,但此时键盘输入的信息会停留在内存当中,当下次程序需要输入流中的数据时,会直接读取该内存存在的值(而逻辑上这个值是报过错却没有删掉的),所以继续抛出异常,导致无限循环。

第②种情况的解决方法有三种:
假设实例化对象语句为Scanner scan=new Scanner(System.in);

  1. 在try catch块的异常处理时,声明一个scan.next();这一句话的作用是读取一次内存中的内容,这样等待键盘输入内存中的数据被清空,下一次可以输入。
  2. 每次使用Scanner之前,new Scanner(SyStem.in);也能解决问题,但是这样做非常的消耗性能。
  3. 每一个输入都使用nextLine();接收输入后,对接收的数据进行类型的强制转换。类型无法转换会抛出异常。

代码如下

package lab3;

import java.util.*;
import java.io.*;

public class catchNoint {
	public static void main(String[] args) {
		//先完成对整数求和的主功能
		int number,SUM;
		boolean flag_over=false;
		Scanner scan=new Scanner(System.in);
		number=0;
		SUM=0;
		while (!flag_over){
			//
		    try{
		       System.out.println("请输入一个整数进行累加操作(累加结束标志为输入整数999):");
               SUM += number;
               number = 0;							//number实时刷新一下,即使读入非整数也不会计入
        	   number= scan.nextInt();					//将输入转化为整数型
		       if(number==999){flag_over=true;}
               } catch (InputMismatchException e){
            	   //抛出输入异常警告
		           System.out.println("输入数据不合法,请重新输入!");
		           scan.next();}
         }
        System.out.println("累加和为" + SUM);
		}
}

输出:

请输入一个整数进行累加操作(累加结束标志为输入整数999)1
请输入一个整数进行累加操作(累加结束标志为输入整数999)2
请输入一个整数进行累加操作(累加结束标志为输入整数999)999.6
输入数据不合法,请重新输入!
请输入一个整数进行累加操作(累加结束标志为输入整数999)999
累加和为3


Lab3_2

题目:Modify the program on the previous question. By adding an exception to the negative input, no summing operation is performed on the negative input.

分析
题目意思即为:
修改上一个问题lab3_1的程序。检测输入中为负数的数据,添加异常,进行报错处理,同时若为负输入,则不执行计和操作。

这道题学到的:

  1. try-catch可以处理多个异常,但注意对应throw-catch的使用

  2. throws 关键字和 throw 关键字在使用上的几点区别
    ①throws 用来声明一个方法可能抛出的所有异常信息,throw 则是指拋出的一个具体的异常类型。
    ②通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息。
    ③throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw 则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。

  3. 关于java报错“Cannot make a static reference to the non-static ”,最开始为了使用throws定义了一个public void方法testNegetive()进行负数输入的捕获,忘记了main函数本身是static不能直接调用非静态函数,需要在运行部分先实例化一个对象temp,通过temp.testNegetive(i)调用

代码如下

package lab3;

import java.util.*;
import java.io.*;

public class catchNoint {
	public void testNegative(int i) throws Exception{
	     if(i < 0){
	            throw new Exception();
	     }
	}
	public static void main(String[] args) {
		
		//先完成对整数求和的主功能
		int number,SUM;
		boolean flag_over=false;
		Scanner scan=new Scanner(System.in);
		number=0;
		SUM=0;
		while (!flag_over){
			//
		    try{
		       catchNoint temp=new catchNoint();
		       System.out.println("请输入一个整数进行累加操作(累加结束标志为输入整数999):");
		       SUM += number;
               number = 0;							//number实时刷新一下,即使读入非整数也不会计入
        	   number= scan.nextInt();				//将输入转化为整数型 
		       temp.testNegative(number);			//输入为负数,进行异常处理 
		       if(number==999){flag_over=true;}
               } catch (InputMismatchException e){
            	   									//输入为非整数,抛出输入异常警告
		           System.out.println("输入数据不合法,请重新输入!");
		           scan.next();
		        }catch(Exception e){
	        	   System.out.println(number+"为负数,请重新输入!");
	        	   number=0;		        
	        	}
         }
        System.out.println("累加和为" + SUM);
		}
}

输出:

请输入一个整数进行累加操作(累加结束标志为输入整数999)1
请输入一个整数进行累加操作(累加结束标志为输入整数999)2
请输入一个整数进行累加操作(累加结束标志为输入整数999)-3
-3为负数,请重新输入!
请输入一个整数进行累加操作(累加结束标志为输入整数999)0.6
输入数据不合法,请重新输入!
请输入一个整数进行累加操作(累加结束标志为输入整数999)999
累加和为3

Lab3_3

题目:Use HashMap to simulate an online shopping cart. Requirement: Enter the name, unit price, and purchase quantity of five books from the keyboard, store these information in a HashMap, and then call the method getSum(HashMap books) with this HashMap as a parameter. This method is used to calculate the total price of the books. Tip: Keyboard input can use the Scanner class.

分析
题目意思即为:
使用java中的散列表类——HashMap,模拟在线购物车。
要求:从键盘输入五本书的名称、单价和购买数量,将这些信息存储在哈希表中,然后调用此HashMap作为参数获取购买总花费金额。此方法用于计算图书的总价格。提示:键盘输入可以使用Scanner类。

这道题学到的:
以实例化对象:HashMap<Integer,book> books= new HashMap<Integer,book>();//book为自定义类为例

  1. HashMap的一些基本操作:参考来源

①增加函数:

int x=books.size();
books.put(x, item); 

②遍历函数:

for (Integer i : books.keySet()) {
     //具体操作}
  1. java中非静态内部类不能有静态变量,却可以定义静态常量
    java类加载时,先执行加载外部类,再加载内部类,最后初始化内部类中的变量,相当于说java中要加载内部类必须在实例化外部类之后完成,而这个时候如果内部类中的变量是静态的,就会使得当“外部类还没有实例化,内部类还没有被加载的时候”,内部类的属性就已经起作用了,这样明显是有矛盾的。
    所以java不允许这样做。而java常量放在内存中常量池,它的机制与变量是不同的,编译时,加载常量是不需要加载类的,所以内部非静态内部类允许静态常量的存在。
    从运用方面也可以解释为:内部类没有被实例化,也就无法使用内部类的静态属性,那么即使内部类的静态属性被初始化了,也没有任何作用。

代码如下

package lab3;

import java.util.HashMap;
import java.util.Scanner;

public class onlineShopping {
	/*online shopping
	 * 使用HashMap模拟在线购物车。
	 * 要求:
	 * 从键盘输入五本书的名称、单价和购买数量
	 * 将这些信息存储在HashMap中,
	 * 然后调用此HashMap作为参数的方法获取Sum(哈希映射书)。
	 * 此方法用于计算图书的总价格。
	 * 提示:键盘输入可以使用扫描仪类。 */
	//书的相关信息
	public static int book_num=0;
	public class book{
		private String name;
		private double price;
		private int number;
		public book(String name,double price,int number) {
			this.name=name;
			this.price=price;
			this.number=number;
			book_num++;
		}
		public String bookGet() {
			String str="";
			str="书籍名称:"+name+" 书籍单价:"+price+" 书籍数目:"+number;
			return str;
			
		}
		public double sum() {
			double money=0;
			money=money+price*(double)number;
			return money;
		}
	}

	HashMap<Integer,book> books= new HashMap<Integer,book>();
	//使用HashMap模拟在线购物车
	public void addBook(){ 
         System.out.println("请输入书籍名称:");
         Scanner scan = new Scanner(System.in);
         String name = scan.nextLine();
         
         System.out.println("请输入该书籍单价价格:");
         double price = scan.nextDouble();
      
         System.out.println("请录入欲购买书目:");
         int number = scan.nextInt();
         
         book item=new book(name,price,number);
         int x=books.size();
         books.put(x, item);   
     }

		 //展示散列表信息并输出总金额
	public void displayItem(){
	         System.out.println("当前购物篮中共有:"+books.size()+"件商品:");
	         double sum=0;
	         // 输出 key 和 value
	         for (Integer i : books.keySet()) {
	             System.out.println("商品: " + i + " 对应信息为: " + books.get(i).bookGet());
	             sum=sum+books.get(i).sum();
	            }
	         System.out.println("总开销为:"+sum);
	 }

	public static void main(String[] args) {
		Scanner scan_temp = new Scanner(System.in);
		onlineShopping myList = new onlineShopping();
        int userOpt = 0;
        while (userOpt != 3) {
            System.out.println("");
            System.out.println("----- 功能目录------");
            System.out.println("(1) 加入购物车 ");
            System.out.println("(2) 展示购物车并显示当前总开销. ");
            System.out.println("(3) 退出 ");
            userOpt = scan_temp.nextInt();  
            if (userOpt == 1) {
            myList.addBook();

            }
            if (userOpt == 2) {
            myList.displayItem();
            }
        }
		
	}

}

输出:


----- 功能目录------
(1) 加入购物车 
(2) 展示购物车并显示当前总开销. 
(3) 退出 
1
请输入书籍名称:
小王子
请输入该书籍单价价格:
32
请录入欲购买书目:
1

----- 功能目录------
(1) 加入购物车 
(2) 展示购物车并显示当前总开销. 
(3) 退出 
1
请输入书籍名称:
c primer plus
请输入该书籍单价价格:
50
请录入欲购买书目:
1

----- 功能目录------
(1) 加入购物车 
(2) 展示购物车并显示当前总开销. 
(3) 退出 
2
当前购物篮中共有:2件商品:
商品: 0 对应信息为: 书籍名称:小王子 书籍单价:32.0 书籍数目:1
商品: 1 对应信息为: 书籍名称:c primer plus 书籍单价:50.0 书籍数目:1
总开销为:82.0

----- 功能目录------
(1) 加入购物车 
(2) 展示购物车并显示当前总开销. 
(3) 退出 
3


lab3_4

题目:
Use Java GUI to read and write a text files, and meet the following requirements: (1)The interface includes two buttons and a text display area. (2) The function of one button is to read one file and display the text content in the text display area; The function of the other button is to write the contents of the text display area to another file.

分析
使用Java GUI读写文本文件,满足以下要求:
(1)界面包括两个按钮和一个文本显示区。
(2)一个按钮的功能是读取一个文件,在文本显示区显示文本内容;
(3)另一个按钮的功能是将文本显示区域的内容写入另一个文件。

这道题学到的:

  1. Java的GUI编程中对操作的界面编写,一般编程的思路是:
    ①对相应菜单项设置动作监听
    ②当激活动作发生时(例如鼠标的点击),会显示相应文件操作子窗口,进行操作
  2. 相关操作都需要先对字符串形式的文件名用File类包装,然后用FileReader或FileWriter文件流包装,再进行读写操作了。另外还需对文件读写进行异常捕获和处理。
  3. 接口中定义的函数需要重写,必须要在类中实现。
  4. 实际操作中发现FileReader是没有办法指定编码而出现了乱码的情况,而FileReader的父类InputStreamReader可以指定编码“utf-8”,所以我们可以替换FileReaser,用InputStreamReader来解决乱码问题。

代码如下

package lab3;

import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.awt.FileDialog;
import java.awt.Frame;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import javax.swing.*;
import java.awt.FlowLayout;

/*
(1)界面包括两个按钮和一个文本显示区。
(2)一个按钮的功能是读取一个文件,在文本显示区显示文本内容;
(3)另一个按钮的功能是将文本显示区域的内容写入另一个文件。
*/

public class GUI extends Frame implements ActionListener{
    private Button btn1;
    private Button btn2;
    private Frame f;
    private FileDialog fd;
    private File file=null;
    private TextArea ta;//文本显示区
    
    //构造函数
    public GUI() {
    	btn1=new Button("读取文件");
    	btn2=new Button("保存到本地");
    	ta=new TextArea(20,50);
    	btn1.addActionListener(this);
    	btn2.addActionListener(this);//给按钮添加事件监听器
    	}
    //给按钮添加行为
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==btn1) { //单击按钮1时   
              fd = new FileDialog(f,"Open",FileDialog.LOAD);
              fd.setVisible(true);   //创建并显示打开文件对话框
 
              try {   //以缓冲区方式读取文件内容
            	  file = new File(fd.getDirectory(),fd.getFile());
            	  FileInputStream fr = new FileInputStream(file);
                  InputStreamReader reader = new InputStreamReader(fr,"UTF-8");
                  BufferedReader br = new BufferedReader(reader);
                  String line;
                  while ((line = br.readLine()) != null) {
                	  ta.append(line+"\r\n");
                      //System.out.println(line);
                  }
                  fr.close();
                  br.close();
                  reader.close();
                }catch (IOException ioe){
                	System.out.println(ioe);
                 }
         }   
        if(e.getSource()==btn2) { 
            try {   
            	String content=ta.getText();
            	File f=new File("D://java/practise.txt");//向指定文本框内写入
            	FileWriter fw=new FileWriter(f);
            	fw.write(content);
            	fw.close(); 
            	System.out.println("保存成功!");
            	}catch(IOException ioe){
                	System.out.println(ioe);
            	}
        }
    }
    public void show(){
    	f = new Frame("GUI界面练习");         //初始化对象f
        f.setSize(500,500);                //设置窗口f的大小
        //设置布局管理器为FlowLayout
        f.setLayout(new FlowLayout(FlowLayout.LEFT,30,20));
        f.add(btn1);   
        f.add(btn2); 
        f.add(ta);               
        //为窗口f添加WindowListener监听器
        f.addWindowListener(new WindowAdapter(){
        	public void windowClosing(WindowEvent evt){ //实现windowClosing方法
        		f.setVisible(false);         //设置窗口f不可见
                f.dispose();            //释放窗口及其子组件的屏幕资源
                System.exit(0);            //退出程序
            }
           });
        f.setLocation(200,200);
        f.setVisible(true);                //设置窗口f可视
}	
	public static void main(String[] args) {
		GUI iof = new GUI();
        iof.show();
    }

}

运行结果:
“读取文件”从本地导入了文件“将进酒”的内容:
在这里插入图片描述
然后我对文本框中显示内容进行了删改,点击“保存到本地”按钮将当前文本框中的内容保存到“practise”这一文件中
在这里插入图片描述

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值