JAVA博客作业(三)

一、前言

  (1)涉及知识点

      ①abstract抽象类的设计

      ②接口的使用方法

      ③comparable类、comparator类、ArrayList arr=new ArrayList();的使用

      ④加强for循环的使用

  (2)题量评估

      题集7:一般

      题集8:一般

      题集9:一般

  (3)难度评估

      题集7:困难

      题集8:困难

      题集9:一般

二、设计与分析

  (1)7-1 图形卡片排序游戏(一)&&7-2 图形卡片分组游戏(二)

 

Comparable接口

Comparable接口在JDK8中的源码:

 

1 package java.lang;
2 import java.util.*;
3 
4 package java.lang;
5 public interface Comparable<T> {
6     public int compareTo(T o);
7 }

int compareTo(T o)

比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

Comparator类
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。

重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大o2;如果返回0,表示相等;返回负整数,表示o1小于o2。

可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。

还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

ArrayList<Integer>的使用:

1.添加元素

ArrayList<Integer> list= new ArrayList<Integer>();
list.add(1);
list.add(54);

2.最大最小值————— Collections.max(list),mina = Collections.min(list);

3.拷贝

ArrayList<Integer> list2 = new ArrayList<Integer>();

list2.addAll(list);

4.排序

Collections.sort(list);

5.倒序

Collections.reverse(list);

6.求的某元素首次出现位置

int i = list.indexOf(23);//list中23元素首次出现的位置

8.求和

int sum = 0;
for (int i=0;i<list2.size();i++){
    sum += list2.get(i);
}
System.out.println("list2 sum is "+sum);


//利用stream求和
List<Integer> ls = new ArrayList<Integer>();
ls.add(43);
ls.add(27);
int sum2 = ls.stream().mapToInt(a->a).sum();
System.out.println("sum is "+sum2);

设计思路

设计图形抽象类,使其他图形可以继承共同特点,又可对不同之处进行重写:

abstract class Shape{//图形抽象类
    private String type;
    Shape(){}
    Shape(String type){//构造图形
        this.type = type;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public abstract double getArea();//抽象方法——获得面积
    public abstract boolean validate();//抽象方法——获得判断
    @Override
    public String toString() {//返回结果
        return this.type;
    }
}

设计具体图形类,并继承图形类

  1 class Circle extends Shape {
  2     private double r;
  3     private double area;
  4     Circle(){}
  5     Circle(double radius){
  6         this.r = radius;
  7     }
  8     public double getR() {
  9         return r;
 10     }
 11     public void setR(double r) {
 12         this.r = r;
 13     }
 14     @Override
 15     public double getArea() {
 16         this.area = r*r*Math.PI;
 17         return area;
 18     }
 19     @Override
 20     public boolean validate() {
 21         if (r>0){
 22             return true;
 23         }
 24         else return false;
 25     }
 26 }
 27 class Rectangle extends Shape {//长方形
 28     private double length;
 29     private double width;
 30     private double area;
 31     Rectangle(){}
 32     Rectangle(double l,double w){
 33         this.length = l;
 34         this.width = w;
 35     }
 36     public void setWidth(double width) {
 37         this.width = width;
 38     }
 39     public void setLength(double length) {
 40         this.length = length;
 41     }
 42     public double getLength() {
 43         return length;
 44     }
 45     public double getWidth() {
 46         return width;
 47     }
 48 
 49     @Override
 50     public double getArea() {
 51         this.area = this.length*this.width;
 52         return this.area;
 53     }
 54     @Override
 55     public boolean validate() {
 56         if (length>0&&width>0){
 57             return true;
 58         }
 59         else return false;
 60     }
 61 }
 62 class Triangle extends Shape {//三角形
 63     private double a;
 64     private double b;
 65     private double c;
 66     Triangle(){}
 67     Triangle(double l1,double l2,double l3){
 68         this.a = l1;
 69         this.b = l2;
 70         this.c = l3;
 71     }
 72     @Override
 73     public double getArea() {
 74         double p = 0.5*(a+b+c);
 75         double area = p*(p-a)*(p-b)*(p-c);
 76         return Math.pow(area,0.5);
 77     }
 78 
 79     @Override
 80     public boolean validate() {
 81         if (a>0&&b>0&&c>0&&(a+b>c&&a+c>b&&b+c>a)){
 82             return true;
 83         }else {
 84             return false;
 85         }
 86     }
 87 }
 88 class Trapezoid extends Shape {//梯形
 89     double h;
 90     double hl;
 91     double dl;
 92     Trapezoid(){}
 93     Trapezoid(double hl,double dl,double h){
 94         this.hl = hl;
 95         this.dl = dl;
 96         this.h = h;
 97     }
 98     @Override
 99     public double getArea() {
100         double area = (hl+dl)*h*0.5;
101         return area;
102     }
103     @Override
104     public boolean validate() {
105         if (hl>0&&dl>0&&h>0){
106             return true;
107         }else
108             return false;
109     }
110 }

创建一个新的类,继承comparable类,用来进行图形的比较:

 1 class C implements Comparable<C>{//创建接口(implement) 继承comparable类,重写比较方法
 2     private Shape shape;
 3     public C(){}
 4     public C(Shape shape){
 5         this.shape = shape;
 6     }
 7     public void setShape(Shape shape) {
 8         this.shape = shape;
 9     }
10 
11     public Shape getShape() {
12         return shape;
13     }
14 
15     @Override
16     public int compareTo(C card) {
17         return -(int)(shape.getArea()-card.getShape().getArea());
18     }
19 }

设计一个类专门负责对输入制的处理,通过调用这个类的创建方法来判断应该创建什么类型的卡片,完成对象的建造,并在这个类中设计相应的值得判断、整体排序、整体面积输出等游戏功能

class DealCardList{
    ArrayList<C> cardList =new ArrayList<>();
    DealCardList(){}
    DealCardList(ArrayList<Integer> list){
        for(Integer card:list){//便利list数组,将其存入card中
            switch (card){//将图形存入cardlist
                case 1://圆形
                    double r = work7_1.Game.input.nextDouble();
                    C card1 = new C(new Circle(r));
                    card1.getShape().setType("Circle");
                    cardList.add(card1);
                    break;
                case 2://矩形
                    double h = work7_1.Game.input.nextDouble();
                    double w = work7_1.Game.input.nextDouble();
                    C card2 = new C(new Rectangle(h,w));
                    card2.getShape().setType("Rectangle");
                    cardList.add(card2);
                    break;
                case 3://三角形
                    double a = work7_1.Game.input.nextDouble();
                    double b = work7_1.Game.input.nextDouble();
                    double c = work7_1.Game.input.nextDouble();
                    C card3 = new C(new Triangle(a,b,c));
                    card3.getShape().setType("Triangle");
                    cardList.add(card3);
                    break;
                case 4://梯形
                    double hl = work7_1.Game.input.nextDouble();
                    double dl = work7_1.Game.input.nextDouble();
                    double l = work7_1.Game.input.nextDouble();
                    C card4 = new C(new Trapezoid(hl,dl,l));
                    card4.getShape().setType("Trapezoid");
                    cardList.add(card4);
                    break;
            }

        }
    }
    public boolean validate(){//有效性
        for(C card:cardList){
            if (!card.getShape().validate()){
                return false;
            }
        }
        return true;
    }
    public void cardSort(){//做排序
        TreeSet<C> cards = new TreeSet<>(cardList);
        for (C card : cards) {
            System.out.print(card.getShape()+":");
            System.out.printf("%.2f ",card.getShape().getArea());
        }
    }
    public double getAllArea(){
        double sum = 0;
        for (C card : cardList){
            sum+=card.getShape().getArea();
        }
        return sum;
    }
    public void showResult(){
        System.out.println("The original list:");//大家的面积
        for (C card : cardList){
            System.out.print(card.getShape()+":");
            System.out.printf("%.2f ",card.getShape().getArea());
        }
        System.out.println();
        System.out.println("The sorted list:");//排序后的面积
        cardSort();
        System.out.println();
        System.out.printf("Sum of area:%.2f",getAllArea());//要用printf才能使用%.2f
    }
}

 在主函数中首先创建ArrayList<Integer> list = new ArrayList<Integer>();用于输入数据的存放,然后进行输入的数据校验,第一次校验合格后在进行下一步卡片的创建。在卡片创建时再对输入的各个参数进行校验,当一切校验完成后再进行相应数值的计算并输出

 

  (2)7-3 ATM机类结构设计(一)&&7-1 ATM机类结构设计(二)

 设计思路

设计银行(Bank类),带有银行姓名,ATM列表

设计用户类(Account类),带有用户、账户、密码、金额数。用于虚拟构建一个用户

设计存款机(ATM类)完成对ATM机功能的实现,可进行卡号校验、金额校验、操作校验、余额查询等功能的实现

  1 class Bank{
  2     String bankname;
  3     ArrayList<String> AList;
  4     public Bank(){
  5     }
  6     public Bank(String name,ArrayList<String> ATM){
  7         this.bankname = name;
  8         this.AList = ATM;
  9     }
 10     public void setAList(ArrayList<String> AList) {
 11         this.AList = AList;
 12     }
 13 
 14     public void setBankname(String bankname) {
 15         this.bankname = bankname;
 16     }
 17 
 18     public String getBankname() {
 19         return bankname;
 20     }
 21 
 22     public ArrayList<String> getAList() {
 23         return AList;
 24     }
 25 
 26 }
 27 class Account{
 28     private String Uname;//用户
 29     private String account;//账户
 30     private String password;//账户密码
 31     private double money;
 32     ArrayList<String> cardList = new ArrayList<>();
 33     public Account(){
 34     }
 35     public Account(String name,String account,String password,double money,ArrayList<String> cardList){
 36         this.account = account;
 37         this.Uname = name;
 38         this.password = password;
 39         this.cardList = cardList;
 40         this.money = money;
 41     }
 42 
 43     public ArrayList<String> getCardList() {
 44         return cardList;
 45     }
 46 
 47     public double getMoney() {
 48         return money;
 49     }
 50 
 51     public void setMoney(double money) {
 52         this.money = money;
 53     }
 54 
 55     public String getAccount() {
 56         return account;
 57     }
 58 
 59     public String getUname() {
 60         return Uname;
 61     }
 62 
 63     public String getPassword() {
 64         return password;
 65     }
 66 }
 67 class ATM{
 68 
 69     ArrayList<Account> accountList;
 70     ArrayList<Bank> atmList;
 71     String card;
 72     String password;
 73     String Ano;
 74     double money;
 75     boolean check = false;
 76     int location = 0;
 77     int Blocation = 0;
 78     public ATM(ArrayList<Account> accountList,ArrayList<Bank> ATMList,String card,String password,String no,double money){//更改内容构造向ATM存入数据
 79         this.Ano = no;
 80         this.accountList = accountList;
 81         this.money = money;
 82         this.card = card;
 83         this.password = password;
 84         this.atmList = ATMList;
 85     }
 86     public ATM(ArrayList<Account> accountList,String card){//查看金额构造
 87         this.accountList = accountList;
 88         this.card = card;
 89     }
 90 
 91     public void setAno(String ano) {
 92         Ano = ano;
 93     }
 94 
 95     public String getAno() {
 96         return Ano;
 97     }
 98     public void CheckATMno(){//ATM编号校验
 99         int i;
100         int j;
101         int flag = 0;
102         for(i = 0;i<atmList.size();i++){
103             for (j=0;j<atmList.get(i).getAList().size();j++){
104                 if (Ano.equals(atmList.get(i).getAList().get(j))){
105                     flag = 1;
106                     Blocation = i;
107                     break;
108                 }
109             }
110             if (flag == 1){
111                 break;
112             }
113         }
114         if (flag==0){//没找到
115             System.out.println("Sorry,the ATM's id is wrong.");
116             check = false;
117         }
118     }
119     public void CheckUser(){//用户校验(卡号存在性)
120         int i;
121         int j;
122         for (i=0;i<accountList.size();i++){//账号是否存在
123             for (j = 0;j<accountList.get(i).getCardList().size();j++) {
124                 if (card.equals(accountList.get(i).getCardList().get(j))) {
125                     check = true;
126                     this.location = i;
127                     break;
128                 }
129             }
130             if (check == true){
131                 break;
132             }
133         }if(check == false) {//没找到卡号
134             System.out.println("Sorry,this card does not exist.");
135         }
136     }
137     public void CheckKey() {//密码校验
138         if (check == true) {
139             if (!password.equals(accountList.get(location).getPassword())) {//密码错误
140                 System.out.println("Sorry,your password is wrong.");
141                 check = false;
142             }
143         }
144     }
145     public boolean CheckMoney(){//金额校验
146         if (money>0&&(accountList.get(location).getMoney()-money)<0){
147             System.out.println("Sorry,your account balance is insufficient.");
148             return false;
149         }else return true;
150     }
151     public void UserChange(){//用户操作
152         double exMoney = accountList.get(location).getMoney()-money;
153         accountList.get(location).setMoney(exMoney);
154     }
155     public void moneyCheck(){//金额查询
156         System.out.printf("¥%.2f\n",accountList.get(location).getMoney());
157     }
158     public void CheckCrossBank(){//跨行校验,05、06号机器——中国工商
159 
160     }
161     public void menu(){
162         if(money<0) {
163             System.out.printf(accountList.get(location).getUname() + "在" + atmList.get(Blocation).getBankname() + "的" + Ano + "号ATM机上存款¥%.2f\n",Math.abs(money));
164         }else {
165             System.out.printf(accountList.get(location).getUname() + "在" + atmList.get(Blocation).getBankname() + "的" + Ano + "号ATM机上取款¥%.2f\n",money);
166         }
167         System.out.printf("当前余额为¥%.2f\n",accountList.get(location).getMoney());
168     }
169 }

主函数部分:

首先要进行数据的存储。运用ArrayList<String>a= new ArrayList<>()的功能,完成如ATM机号列表、卡号账户列表的创建。再使用ArrayList<类>= new ArrayList<>(),将其中的类替换为银行类/用户类,即可再创建出相应的类列表,作为数据库,方便后期的查找校验。

 

 功能部分,首先对输入进行判断,再调用ATM相关校验函数完成用户相应操作

Scanner scanner = new Scanner(System.in);
        String uinput;
        uinput = scanner.nextLine();
        while (!uinput.equals("#")){
            String[] user=uinput.split("\\s+");
            if (user.length==1){//只查看存款
                ATM atm1 = new ATM(Account,user[0]);
                atm1.CheckUser();
                atm1.moneyCheck();
            }else if (user.length!=1){//
                ATM atm2 = new ATM(Account,ATMList,user[0],user[1],user[2],Double.parseDouble(user[3]));
                atm2.CheckUser();//检验账户存在问题
                atm2.CheckKey();//检验密码
                atm2.CheckATMno();//校验ATM编号是否存在
                if (atm2.check == true) {//卡号存在、密码正确、ATM编号正确——进行存取操作
                    if (atm2.CheckMoney()==true){//钱数充足
                        atm2.UserChange();
                        atm2.menu();
                    }
                }

            }
            uinput = scanner.nextLine();
        }

 第二次ATM实验在原有基础上进行改动,相对简单不少,基于原有的类形式仅增加了税率属性设置,更改了菜单的样式。在本次作业中修补了原先无法实现跨行检测的bug。

增添功能:

①透支操作

public boolean TzChange(){//透支操作
        double tMoney = Math.abs(money-accountList.get(location).getMoney());
        double sxMoney = 0;
        if (tMoney<50000) {//可以透支
            if (accountList.get(location).getMoney()<=0){//没有余额
                sxMoney=money*tCharge;
            }else {//有余额
                sxMoney=tMoney*tCharge;
            }
            accountList.get(location).setMoney(-(tMoney+sxMoney+cCharge));
            return true;
        }else {//违规透支
            return false;
        }
    }

②税率设置

public Bank(String name,ArrayList<String> ATM,double charge){
        this.bankname = name;
        this.AList = ATM;
        this.charge = charge;//新增税率设置
    }

三、踩坑心得

  ①起初不了解ArrayList<>类、加强for循环的使用环境与方法的很多功能,在实际项目中使用后发现是真的好用

  ②类的设计不够好,部分功能没有进行准确的封装,比如在写ATM管理的题目时,基本对原先的功能如金额校验等进行了重写。

四、改进建议

  ①ATM机的题还应该再次对ATM类进行修改,,目前的功能实现都是由主函数直接调用ATM中的功能。应该争取将主函数中的判断部分都交由ATM实行,仅在主函数中仅构造出一个ATM就可以完成全部工作。

五、总结

  这三次作业的题量整体是不多的,难得主要是对所有学过的知识的综合运用,很多时候编程都存在着拿不准应该使用什么结构,运用什么类更合适的问题,大部分的作业还需要去借鉴CSDN上的思路才完成。个人独立编写程序的能力还有很大的提升空间。在试验时也发现自己对于虚拟类的使用以及各种继承、重写、接口的使用方法都不是很了解,还需要在这些方面进行提升,

posted on 2021-12-18 23:22  喵^ω^  阅读(49)  评论(0)    收藏  举报

导航