Java教程

Java学习第一次记录

本文主要是介绍Java学习第一次记录,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

第一次Java学习blog

  • 第一次Java学习blog
    • 前言
      • 关于java学习
      • 1.知识点
      • 2.题量
      • 3.难度
    • 设计分析
      • 题目集二7.2
        • 1.源代码
        • 2.源代码分析
        • 3.心得
      • 题目集三 7.1
        • 1. 源代码
        • 2.类图
        • 3.源代码分析
        • 4.心得
      • 题目集三 7.2
        • 1.源代码
        • 2.类图
        • 3.源代码分析
        • 4.心得
      • 题目集三7.3
        • 1.源代码
        • 2.类图
        • 3.源代码分析
        • 4.心得
    • 踩坑心得
      • 1.java double精度问题
      • 2.RS232串口通信协议
      • 3.习题集三7.2天数差
      • 4.习题集三计算天数的下一天
      • 4.习题集三7.3类之间的调用关系
    • 改进意见
      • 1.关于习题集三7.2月份判断
      • 2.减少不必要的代码
    • 总结
      • 1.学习成果
      • 2.改进和意见

前言

关于java学习

1.知识点

  • 1.java基本语法
  • 2.String类的使用
  • 3.RS232串口通信协议
  • 4.方法的定义和调用
  • 5.定义类和创建对象

2.题量

作业题量相较于上学期的C语言课程减少了很多,但是花费的时间更多了。

3.难度

对比上个学期的C语言作业,本学期的java难度提高了很多,无论是在程序的设计上面还是在边界的判断方面都有很大的提升,尤其是对于程序的边界判断有很大的难度提升 。


设计分析

题目集二7.2

1.源代码

public class Main {
    public static void main(String[] args) {
        try (java.util.Scanner input = new java.util.Scanner(System.in)) {
            String arr;
            int count = 0;
            arr = input.nextLine();
            int len = arr.length();
            boolean flag = false;// 判断是否为无效数据
            for (int i = 0; i < arr.length(); i++) {
                if (arr.charAt(i) == '0') {
                    flag = true;
                    break;
                }
            }
            if (len < 11) {
                System.out.println("null data");
            } else {
                if (!flag) {
                    System.out.println("null data");
                } else {
                    int i = 0;
                    for (; i < arr.length(); i++) {
                        int cnt = 0;
                        if (arr.charAt(i) == '0') {
                            i++;
                            boolean judge1 = true;
                            boolean judge2 = true;
                            String ans = "";
                            for (; i < arr.length() && ans.length() != 8; i++) {
                                if (arr.charAt(i) == '1') {
                                    cnt++;
                                }
                                ans = ans + arr.charAt(i);
                            } // 检测边界问题 正常跳出时 已经为校验为
                            if (i >= arr.length()) {
                                break;
                            }
                            if (cnt % 2 == 1) {
                                if (arr.charAt(i) != '0') {
                                    judge1 = false;
                                }
                            } else {
                                if (arr.charAt(i) != '1') {
                                    judge1 = false;
                                }
                            }
                            i++;
                            if (i >= arr.length()) {
                                break;
                            }
                            if (arr.charAt(i) != '1') {
                                judge2 = false;
                            }
                            if (judge1 && judge2) {// 1:11101011
                                System.out.println((++count) + ":" + ans);
                            } else if (judge1 == false && judge2 == true) {
                                System.out.println((++count) + ":" + "parity check error");
                            } else if (judge2 == false) {
                                System.out.println((++count) + ":" + "validate error");
                            }
                        }
                    }
                }
            }
        }
    }
}

2.源代码分析

  • 1.利用String类对代码进行逐个字符的便利与拆封,从而判断该段字符的合法性
  • 2.设置两个boolean类型变量对字符串进行相应的输出判定

3.心得

  • 该题目使用的RS232是串口通信协议的奇偶校验是计算机上一种非常通用的设备通信协议,其中的奇偶校验是该题的解题关键,奇/偶校验(ECC)是数据传送时采用的一种校正数据错误的一种方式,分为奇校验和偶校验两种。如果是采用奇校验,在传送每一个字节的时候另外附加一位作为校验位,当实际数据中“1”的个数为偶数的时候,这个校验位就是“1”,否则这个校验位就是“0”,这样就可以保证传送数据满足奇校验的要求。在接收方收到数据时,将按照奇校验的要求检测数据中“1”的个数,如果是奇数,表示传送正确,否则表示传送错误。同理偶校验的过程和奇校验的过程一样,只是检测数据中“1”的个数为偶数。如0100101偶校验码就是10100101推理偶校验: 当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”,这样就可以保证传送数据满足偶校验的要求。在接收方收到数据时,将按照偶校验的要求检测数据中“1”的个数,如果是偶数个“1”,表示传送正确,否则表示传送错误。Rs232奇偶校验校的都是“1”的个数 。

>具体RS232串口通信协议链接为:https://www.cnblogs.com/ybqjymy/p/12175994.html


题目集三 7.1

1. 源代码

public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);

		double a = Double.parseDouble(input.next());
		double b = Double.parseDouble(input.next());
		double c = Double.parseDouble(input.next());

		if (a == 0) {
			System.out.println("Wrong Format");
			System.exit(0);
		}

		// create a QuadraticEquation object
		QuadraticEquation equation = new QuadraticEquation(a, b, c);
		// get value of b * b - 4 * a * c
		double discriminant = equation.getDiscriminant();

		System.out.println("a=" + equation.getA() +
				",b=" + equation.getB() +
				",c=" + equation.getC() + ":");

		if (discriminant < 0) {
			System.out.println("The equation has no roots.");
		} else if (discriminant == 0) {
			System.out.println("The root is " +
					String.format("%.2f", equation.getRoot1()));
		} else // (discriminant >= 0)
		{
			System.out.println("The roots are " +
					String.format("%.2f", equation.getRoot1())
					+ " and " + String.format("%.2f", equation.getRoot2()));
		}
	}
}

class QuadraticEquation {
	// your code
	private double Root1, Root2;
	private double a, b, c;

	QuadraticEquation(double a, double b, double c) {
		this.a = a;
		this.b = b;
		this.c = c;
	}

	public double getDiscriminant() {
		double ans;
		ans = Math.pow(b, 2) - 4 * a * c;
		return ans;
	}

	public double getRoot1() {
		this.Root1 = (-1 * b + Math.sqrt(this.getDiscriminant())) / 2 / a;
		return this.Root1;
	}

	public double getA() {
		return a;
	}

	public void setA(double a) {
		this.a = a;
	}

	public double getB() {
		return b;
	}

	public void setB(double b) {
		this.b = b;
	}

	public double getC() {
		return c;
	}

	public void setC(double c) {
		this.c = c;
	}

	public double getRoot2() {
		this.Root2 = (-1 * b - Math.sqrt(this.getDiscriminant())) / 2 / a;
		return this.Root2;
	}

}

2.类图

image

3.源代码分析

  • 1.题目只涉及了一个类,通过main函数调用该类进行数据的判断
  • 2.该题主要的难度不大,按照题目要求进行类的设计即可

4.心得

  • 对于浮点数精确度有了更多的认知和了解,java的浮点数和c++有一些不同之处需要学习

题目集三 7.2

1.源代码

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int year = 0;
		int month = 0;
		int day = 0;

		int choice = input.nextInt();

		if (choice == 1) { // test getNextNDays method
			int m = 0;
			year = Integer.parseInt(input.next());
			month = Integer.parseInt(input.next());
			day = Integer.parseInt(input.next());

			DateUtil date = new DateUtil(year, month, day);

			if (!date.checkInputValidity()) {
				System.out.println("Wrong Format");
				System.exit(0);
			}

			m = input.nextInt();

			if (m < 0) {
				System.out.println("Wrong Format");
				System.exit(0);
			}

			System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
			System.out.println(date.getNextNDays(m).showDate());
		} else if (choice == 2) { // test getPreviousNDays method
			int n = 0;
			year = Integer.parseInt(input.next());
			month = Integer.parseInt(input.next());
			day = Integer.parseInt(input.next());

			DateUtil date = new DateUtil(year, month, day);

			if (!date.checkInputValidity()) {
				System.out.println("Wrong Format");
				System.exit(0);
			}

			n = input.nextInt();

			if (n < 0) {
				System.out.println("Wrong Format");
				System.exit(0);
			}

			System.out.print(
					date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
			System.out.println(date.getPreviousNDays(n).showDate());
		} else if (choice == 3) { // test getDaysofDates method
			year = Integer.parseInt(input.next());
			month = Integer.parseInt(input.next());
			day = Integer.parseInt(input.next());

			int anotherYear = Integer.parseInt(input.next());
			int anotherMonth = Integer.parseInt(input.next());
			int anotherDay = Integer.parseInt(input.next());

			DateUtil fromDate = new DateUtil(year, month, day);
			DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

			if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
				System.out.println("The days between " + fromDate.showDate() +
						" and " + toDate.showDate() + " are:"
						+ fromDate.getDaysofDates(toDate));
			} else {
				System.out.println("Wrong Format");
				System.exit(0);
			}
		} else {
			System.out.println("Wrong Format");
			System.exit(0);
		}
	}
}

class DateUtil {

	private int year, month, day;

	public DateUtil(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public boolean checkInputValidity() {// 检测输入的年、月、日是否合法
		int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
			boolean judge = isLeapYear(year);
			if (judge) {// 闰年
				if (leapdays[month - 1] >= day) {
					return true;
				} else {
					return false;
				}
			} else {
				if (commonday[month - 1] >= day) {
					return true;
				} else {
					return false;
				}
			}
		} else {
			return false;
		}
	}

	public boolean isLeapYear(int year) {
		if ((year % 4 != 0) || (year % 100 == 0 && year % 400 != 0)) {
			return false;
		} else {
			return true;
		}
	}

	public DateUtil getNextNDays(int n) {// 取得year-month-day的下n天日期
		int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if(n>100){
			if(isLeapYear(year)){
				n=n-leapdays[this.month-1];
				this.month++;
				if (this.month > 12) {
					this.month = 1;
					this.year++;
				}
			}else{
				n = n - commondays[this.month - 1];
				this.month++;
				if (this.month > 12) {
					this.month = 1;
					this.year++;
				}
			}
		}
		this.day = this.day + n;
		while (true) {
			if (isLeapYear(this.year)) {
				if (this.day > leapdays[this.month - 1]) {
					this.day = this.day - leapdays[this.month - 1];
					this.month++;
					if (this.month > 12) {
						this.month = 1;
						this.year++;
					}
				} else {
					break;
				}
			} else {
				if (this.day > commondays[this.month - 1]) {
					this.day = this.day - commondays[this.month - 1];
					this.month++;
					if (this.month > 12) {
						this.month = 1;
						this.year++;
					}
				} else {
					break;
				}
			}
		}
		DateUtil nextday = new DateUtil(this.year, this.month, this.day);
		return nextday;
	}

	public DateUtil getPreviousNDays(int n) {// 取得year-month-day的前n天日期
		int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		this.day = this.day - n;
		while (true) {
			if (isLeapYear(this.year)) {
				if (this.day <= 0) {
					this.month--;
					if (this.month <= 0) {
						this.month = 12;
						this.year--;
					}
					this.day = this.day + leapdays[this.month - 1];
				} else {
					if (this.day <= leapdays[this.month - 1]) {
						break;
					} else {
						this.day = this.day - leapdays[this.month - 1];
						this.month++;
						if (this.month > 12) {
							this.month = 1;
							this.year++;
						}
						break;
					}
				}
			} else {
				if (this.day <= 0) {
					this.month--;
					if (this.month <= 0) {
						this.month = 12;
						this.year--;
					}
					this.day = this.day + commondays[this.month - 1];
				} else {
					if (this.day <= commondays[this.month - 1]) {
						break;
					} else {
						this.day = this.day - commondays[this.month - 1];
						this.month++;
						if (this.month > 12) {
							this.month = 1;
							this.year++;
						}
						break;
					}
				}
			}
		}
		DateUtil beforeday = new DateUtil(this.year, this.month, this.day);
		return beforeday;
	}

	public boolean compareDates(DateUtil date) {// 比较当前日期与date的大小(先后)
		boolean flag = false;
		if (this.year > date.year) {
			flag = true;
		} else if (this.year == date.year) {
			if (this.month > date.month) {
				flag = true;
			} else if (this.month == date.month) {
				if (this.day > date.day) {
					flag = true;
				} else {
					flag = false;
				}
			} else {
				flag = false;
			}
		} else {
			flag = false;
		}
		return flag;
	}

	public boolean equalTwoDates(DateUtil date) {// 判断两个日期是否相等
		if (this.day == date.day && this.month == date.month && this.year == date.year) {
			return true;
		} else {
			return false;
		}
	}

	public int getDaysofDates(DateUtil date) {// 求当前日期与date之间相差的天数
		int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int ans = 0;
		if (this.equalTwoDates(date)) {
			ans = 0;
		} else {
			if (this.compareDates(date)) {// this更大
				for (int i = date.year; i < this.year; i++) {
					if (isLeapYear(i)) {
						ans += 366;
					} else {
						ans += 365;
					}
				}
				int day1 = 0, day2 = 0;
				if (isLeapYear(this.year)) {
					for (int i = 0; i < this.month - 1; i++) {
						day1 += leapdays[i];
					}
				} else {
					for (int i = 0; i < this.month - 1; i++) {
						day1 += commondays[i];
					}
				}
				day1 += this.day;
				if (isLeapYear(date.year)) {
					for (int i = 0; i < date.month - 1; i++) {
						day2 += leapdays[i];
					}
				} else {
					for (int i = 0; i < date.month - 1; i++) {
						day2 += commondays[i];
					}
				}
				day2 += date.day;
				ans += (day1 - day2);
			} else {
				for (int i = this.year; i < date.year; i++) {
					if (isLeapYear(i)) {
						ans += 366;
					} else {
						ans += 365;
					}
				}
				int day1 = 0, day2 = 0;
				if (isLeapYear(this.year)) {
					for (int i = 0; i < this.month - 1; i++) {
						day1 += leapdays[i];
					}
				} else {
					for (int i = 0; i < this.month - 1; i++) {
						day1 += commondays[i];
					}
				}
				day1 += this.day;
				if (isLeapYear(date.year)) {
					for (int i = 0; i < date.month - 1; i++) {
						day2 += leapdays[i];
					}
				} else {
					for (int i = 0; i < date.month - 1; i++) {
						day2 += commondays[i];
					}
				}
				day2 += date.day;
				ans += (day2 - day1);
			}
		}
		return ans;
	}

	public String showDate() {// 以“year-month-day”格式返回日期值
		Integer y = this.year;
		Integer m = this.month;
		Integer d = this.day;
		String Date = y.toString() + "-" + m.toString() + "-" + d.toString();
		return Date;
	}
}


2.类图

image

3.源代码分析

  • 1.未将代码用累分开,导致很多代码在Main类钟,造成代码的易读性很差,并且复杂的调用关系导致debug十分困难
  • 2.将多种功能分为多个方法,在判断平年和闰年的时候开辟两个数组分别对应两种情况
  • 3.由于代码钟多次要用到闰年和平年的判断,则利用isleapYear()方法进行闰年和平年的判断

4.心得

  • 1.利用各种方法对应各种功能,让代码在结构上可以更加好的调用
  • 2.一个方法对应一个功能,可以让debug的时候更加容易,更加好修改代码

题目集三7.3

1.源代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year;
        int month;
        int day;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            n = input.nextInt();

            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) { // test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println(fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        } else {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
}

class DateUtil {
    private int year, month, day;
    private Day value;

    public Day getDay() {
        return value;
    }

    public void setDay(Day value) {
        this.value = value;
    }

    public DateUtil() {
    }

    public DateUtil(int y, int m, int d) {
        this.day = d;
        this.month = m;
        this.year = y;
        this.setDay(new Day(this.year, this.month, this.day));
    }

    public boolean checkInputValidity() {// 检测输入的年、月、日是否合法
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (this.year >= 1900 && this.year <= 2050 && this.month >= 1 && this.month <= 12 && this.day >= 1
                && this.day <= 31) {
            boolean judge = this.value.getMonth().getYear().isLeapYear();
            if (judge) {// 闰年
                return leapdays[month - 1] >= day;
            } else {
                return commonday[month - 1] >= day;
            }
        } else {
            return false;
        }
    }

    public DateUtil getNextNDays(int n) {
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (n > 100) {
            if (this.getDay().getMonth().getYear().isLeapYear()) {
                n = n - leapdays[this.value.getMonth().getValue() - 1];
                this.getDay().getMonth().monthIncrement();
            } else {
                n = n - commondays[this.getDay().getMonth().getValue() - 1];
                this.getDay().getMonth().monthIncrement();
            }
        }
        this.day = this.day + n;
        this.getDay().setValue(this.day);// ??
        while (true) {
            if (this.getDay().getMonth().getYear().isLeapYear()) {
                if (this.getDay().getValue() > leapdays[this.getDay().getMonth().getValue() - 1]) {
                    this.getDay()
                            .setValue(this.getDay().getValue() - leapdays[this.getDay().getMonth().getValue() - 1]);
                    this.getDay().getMonth().monthIncrement();
                } else {
                    break;
                }
            } else {
                if (this.getDay().getValue() > commondays[this.getDay().getMonth().getValue() - 1]) {
                    this.getDay()
                            .setValue(this.getDay().getValue() - commondays[this.getDay().getMonth().getValue() - 1]);
                    this.getDay().getMonth().monthIncrement();
                } else {
                    break;
                }
            }
        }
        return new DateUtil(this.getDay().getMonth().getYear().getValue(), this.getDay().getMonth().getValue(),
                this.getDay().getValue());
    }

    public DateUtil getPreviousNDays(int n) {
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        this.day = this.day - n;
        this.getDay().setValue(this.day);
        while (true) {
            if (this.getDay().getMonth().getYear().isLeapYear()) {
                if (this.getDay().getValue() <= 0) {
                    this.getDay().getMonth().monthReduction();
                    this.getDay()
                            .setValue(this.getDay().getValue() + leapdays[this.getDay().getMonth().getValue() - 1]);
                } else {
                    if (this.getDay().getValue() > leapdays[this.getDay().getMonth().getValue() - 1]) {
                        this.getDay()
                                .setValue(this.getDay().getValue() - leapdays[this.getDay().getMonth().getValue() - 1]);
                        this.getDay().getMonth().monthIncrement();
                    }
                    break;
                }
            } else {
                if (this.getDay().getValue() <= 0) {
                    this.getDay().getMonth().monthReduction();
                    this.getDay()
                            .setValue(this.getDay().getValue() + commondays[this.getDay().getMonth().getValue() - 1]);
                } else {
                    if (this.getDay().getValue() > commondays[this.getDay().getMonth().getValue() - 1]) {
                        this.getDay().setValue(
                                this.getDay().getValue() - commondays[this.getDay().getMonth().getValue() - 1]);
                        this.getDay().getMonth().monthReduction();
                    }
                    break;
                }
            }
        }
        return new DateUtil(this.getDay().getMonth().getYear().getValue(), this.getDay().getMonth().getValue(),
                this.getDay().getValue());
    }

    public boolean compareDates(DateUtil date) {// 比较当前日期与date的大小(先后)
        boolean flag;
        if (this.year > date.year) {
            flag = true;
        } else if (this.year == date.year) {
            if (this.month > date.month) {
                flag = true;
            } else if (this.month == date.month) {
                flag = this.day > date.day;
            } else {
                flag = false;
            }
        } else {
            flag = false;
        }
        return flag;
    }

    public boolean equalTwoDates(DateUtil date) {// 判断两个日期是否相等
        return this.day == date.day && this.month == date.month && this.year == date.year;
    }

    public int getDaysofDates(DateUtil date) {// 求当前日期与date之间相差的天数
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int ans = 0;
        if (this.equalTwoDates(date)) {
        } else {
            if (this.compareDates(date)) {// this更大
                Year i = new Year(date.year);
                Year a = new Year(this.year);
                Year b = new Year(date.year);
                for (; i.getValue() < a.getValue(); i.yearIncrement()) {
                    if (i.isLeapYear()) {
                        ans += 366;
                    } else {
                        ans += 365;
                    }
                }
                int day1 = 0, day2 = 0;
                if (a.isLeapYear()) {
                    for (int j = 0; j < this.month - 1; j++) {
                        day1 += leapdays[j];
                    }
                } else {
                    for (int j = 0; j < this.month - 1; j++) {
                        day1 += commondays[j];
                    }
                }
                day1 += this.day;
                if (b.isLeapYear()) {
                    for (int j = 0; j < date.month - 1; j++) {
                        day2 += leapdays[j];
                    }
                } else {
                    for (int j = 0; j < date.month - 1; j++) {
                        day2 += commondays[j];
                    }
                }
                day2 += date.day;
                ans += (day1 - day2);
            } else {
                Year i = new Year(this.year);
                Year a = new Year(this.year);
                Year b = new Year(date.year);
                for (; i.getValue() < b.getValue(); i.yearIncrement()) {
                    if (i.isLeapYear()) {
                        ans += 366;
                    } else {
                        ans += 365;
                    }
                }
                int day1 = 0, day2 = 0;
                if (a.isLeapYear()) {// this
                    for (int j = 0; j < this.month - 1; j++) {
                        day1 += leapdays[j];
                    }
                } else {
                    for (int j = 0; j < this.month - 1; j++) {
                        day1 += commondays[j];
                    }
                }
                day1 += this.day;
                if (b.isLeapYear()) {// date
                    for (int j = 0; j < date.month - 1; j++) {
                        day2 += leapdays[j];
                    }
                } else {
                    for (int j = 0; j < date.month - 1; j++) {
                        day2 += commondays[j];
                    }
                }
                day2 += date.day;
                ans += (day2 - day1);
            }
        }
        return ans;
    }

    public String showDate() {// 以“year-month-day”格式返回日期值
        Integer y = this.getDay().getMonth().getYear().getValue();
        Integer m = this.getDay().getMonth().getValue();
        Integer d = this.getDay().getValue();
        return y + "-" + m + "-" + d;
    }
}

class Day {

    private int yearValue, monthValue, dayValue;
    private Month value;

    public int getValue() {
        return dayValue;
    }

    public void setValue(int dayValue) {
        this.dayValue = dayValue;
    }

    public Month getMonth() {
        return value;
    }

    public void setMonth(Month value) {
        this.value = value;
    }

    public Day(int yearValue, int monthValue, int dayValue) {
        this.yearValue = yearValue;
        this.monthValue = monthValue;
        this.dayValue = dayValue;
        this.setMonth(new Month(this.yearValue, this.monthValue));
    }

    public Day() {
    }

    public void resetMin() {
        this.dayValue = 1;
    }

    public void resetMax() {
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (this.value.getYear().isLeapYear()) {
            this.dayValue = leapdays[this.value.getValue() - 1];
        } else {
            this.dayValue = commonday[this.value.getValue() - 1];
        }
    }

    public boolean validate() {
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (this.getMonth().getYear().isLeapYear()) {
            return this.dayValue >= 1 && this.dayValue <= leapdays[this.value.getValue() - 1];
        } else {
            return this.dayValue >= 1 && this.dayValue <= commonday[this.value.getValue() - 1];
        }
    }

    public void dayIncrement() {
        this.dayValue++;// 加一天
    }

    public void dayReduction() {
        this.dayValue--;
    }
}

class Month {
    private int monthValue;
    private Year value;

    public Month() {
    }

    public Month(int yearValue, int monthValue) {
        this.monthValue = monthValue;
        this.setYear(new Year(yearValue));
    }

    public int getValue() {
        return monthValue;
    }

    public void setValue(int monthValue) {
        this.monthValue = monthValue;
    }

    public Year getYear() {
        return value;
    }

    public void setYear(Year value) {
        this.value = value;
    }

    public void resetMin() {
        this.monthValue = 1;
    }

    public void resetMax() {
        this.monthValue = 12;
    }

    boolean validate() {
        return this.monthValue <= 12 && this.monthValue >= 1;
    }

    public void monthIncrement() {
        this.monthValue++;
        if (this.monthValue>12) {
            resetMin();
            value.yearIncrement();
        }
    }

    public void monthReduction() {
        this.monthValue--;
        if (this.monthValue<=0) {
            resetMax();
            value.yearReduction();
        }
    }
}

class Year {

    private int value;

    public int getValue() {
        return this.value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public Year() {
    }

    public Year(int value) {
        this.value = value;
    }

    public boolean isLeapYear() {
        return (this.value % 4 == 0) && (this.value % 100 != 0 || this.value % 400 == 0);
    }

    public boolean validate() {
        if (this.value <= 2050 && this.value >= 1900) {
            return true;
        } else {
            return false;
        }
    }

    void yearIncrement() {
        this.value++;
    }

    void yearReduction() {
        this.value--;
    }
}

2.类图

image

3.源代码分析

  • 1.与7.2功能一样,但是在代码的结构上有很大的不同之处,在该次代码中,将Main,DateUtil,Day,Year分开,加强了代码的可读性
  • 2.该类的调用情况十分不合理,耦合性很强,是一种不规范的代码,调用层次不够清晰

4.心得

  • 1.代码的调用结构关系应该改成Main类调用其他类,降低各个类的耦合性
  • 2.进行代码的设计时,应该提前设计好代码的调用关系,以及设计好代码的类,便于之后的分析

踩坑心得

1.java double精度问题

  • 1.在java中double存在精度丢失的问题,如下所示:
java
public class Main {
    public static void main(String[] args) {
        System.out.println(0.06 + 0.01);
        System.out.println(1.0 - 0.42);
        System.out.println(4.014 * 100);
        System.out.println(303.1 / 1000);
    }
}
  • 该段代码应该输出为
  • 0.07 0.58 401.4 0.3031
  • 实际输出为:
    image

与所需要输出有误差,不可用于作比较,会出现很大的误差

总结:在利用java进行高精度运算时,应该使用BigInteger或者BigDecimal类,使用double类极其容易出现误差,从而影响计算的结果

2.RS232串口通信协议

  • 未理解什么是奇偶校验,但是未查其概念,从而导致自己调试但是仍然无法通过代码的运行,从而浪费大量的时间用来进行代码调试
    >具体RS232串口通信协议链接为:https://www.cnblogs.com/ybqjymy/p/12175994.html

3.习题集三7.2天数差

  • 1.计算天数差时利用暴力方法,从第一天逐个向后求,导致超时问题的出现
  • 2.计算天数差时间,以每四年为一个轮回,但是在不一定每四年会出现一次闰年
  • 3.计算天数差利用了for循环的方式进行计算,容易多加或者少加天和月

心得:在进行代码的设计时应该列一个大纲,设计类图,了解自己要写的代码以及各个类之间的调用关系

4.习题集三计算天数的下一天

  • 1.判断闰年和平年的时候计算二月份的下一天边界问题出错
  • 2.判断每一天的下一天的时候,边界问题容易出错

在每次的计算边界之前给每个边界一个特判,并且在每个边界都要给出边界值进行转换和复位

4.习题集三7.3类之间的调用关系

  • 1.在该题代码中,类的调用关系为单一调用,导致一个类调用另外一个类中间需要进行多次的调用,导致代码易读性十分差,也导致出错率很大
    例如:
   public DateUtil getPreviousNDays(int n) {
        int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int[] commondays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        this.day = this.day - n;
        this.getDay().setValue(this.day);
        while (true) {
            if (this.getDay().getMonth().getYear().isLeapYear()) {
                if (this.getDay().getValue() <= 0) {
                    this.getDay().getMonth().monthReduction();
                    this.getDay()
                            .setValue(this.getDay().getValue() + leapdays[this.getDay().getMonth().getValue() - 1]);
                } else {
                    if (this.getDay().getValue() > leapdays[this.getDay().getMonth().getValue() - 1]) {
                        this.getDay()
                                .setValue(this.getDay().getValue() - leapdays[this.getDay().getMonth().getValue() - 1]);
                        this.getDay().getMonth().monthIncrement();
                    }
                    break;
                }
            } else {
                if (this.getDay().getValue() <= 0) {
                    this.getDay().getMonth().monthReduction();
                    this.getDay()
                            .setValue(this.getDay().getValue() + commondays[this.getDay().getMonth().getValue() - 1]);
                } else {
                    if (this.getDay().getValue() > commondays[this.getDay().getMonth().getValue() - 1]) {
                        this.getDay().setValue(
                                this.getDay().getValue() - commondays[this.getDay().getMonth().getValue() - 1]);
                        this.getDay().getMonth().monthReduction();
                    }
                    break;
                }
            }
        }
        return new DateUtil(this.getDay().getMonth().getYear().getValue(), this.getDay().getMonth().getValue(),
                this.getDay().getValue());
    }
  • 在上述代码中调用Year类的函数需要先调用之前的类才可以调用到该函数,代码可读性十分差,代码复杂度也很高,修改代码成本会十分大

心得:设计类的时候简化类之间的调用关系,让类之间的耦合度降低,增加其可读性,减少其代码修改的成本

改进意见

1.关于习题集三7.2月份判断

  • 源代码为
	public boolean checkInputValidity() {// 检测输入的年、月、日是否合法
   	int[] leapdays = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   	int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   	if (year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
   		boolean judge = isLeapYear(year);
   		if (judge) {// 闰年
   			if (leapdays[month - 1] >= day) {
   				return true;
   			} else {
   				return false;
   			}
   		} else {
   			if (commonday[month - 1] >= day) {
   				return true;
   			} else {
   				return false;
   			}
   		}
   	} else {
   		return false;
   	}
   }
  • 修改后为
 	public boolean checkInputValidity() {// 检测输入的年、月、日是否合法
		int[] commonday = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
			boolean judge = isLeapYear(year);
            boolean flag;
			if (judge) {// 闰年
                if(month==2){
                    if (leapdays[month - 1]+1 >= day) {
                        flag = true;
                    } else {
                        flag = false;
                    }
                }else{
                    if (leapdays[month - 1]+1 >= day) {
                        flag = true;
                    } else {
                        flag = false;
                    }
                }
			} else {
				if (commonday[month - 1] >= day) {
					flag = true;
				} else {
					flag = false;
				}
			}
		} else {
			flag = false;
		}
        return flag;
	}

设置单一出口,增加代码的易读性
只是用一个月份数组,避免空间的浪费

2.减少不必要的代码

	public String showDate() {// 以“year-month-day”格式返回日期值
		Integer y = this.year;
		Integer m = this.month;
		Integer d = this.day;
		String Date = y.toString() + "-" + m.toString() + "-" + d.toString();
		return Date;
	}

修改后为

	public String showDate() {
		return this.year + "-" + this.month + "-" + this.day;
	}

减少多余的代码,减少代码量,做到代码的简洁和严谨


总结

1.学习成果

  • 1.面向对象:在日常生活或编程中,简单的问题可以用面向过程的思路来解决,直接有效,但是当问题的规模变得更大时,用面向过程的思想是远远不够的。所以慢慢就出现了面向对象的编程思想。世界上有很多人和事物,每一个都可以看做一个对象,而每个对象都有自己的属性和行为,对象与对象之间通过方法来交互。面向对象是一种以“对象”为中心的编程思想,把要解决的问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个对象在整个解决问题的步骤中的属性和行为。
  • 2.面向过程:面向过程是一种以事件为中心的编程思想,编程的时候把解决问题的步骤分析出来,然后用函数把这些步骤实现,在一步一步的具体步骤中再按顺序调用函数。
  • 3.经过这三次的练习和这段时间的java学习,我对java有了更加深入的了解,并且对java语言的面向对象特性也有了更加深入的理解,对程序的边界输入判断也有了更多的经验和想法,在代码的规范上也有了很大的提升,并且会对每个类进行封装,从而增强其复用性。
  • 4.在java的边界判断上还有很大的不足,应该增强自身对代码的数据边界问题的判断能力。

2.改进和意见

  • 1.对于课程的作业,希望老师的考察点更加明确,比如第一次作业的浮点问题,用float才可以正常通过,用double则不行,如果该次作业的题目考察的是精度问题,那么我用BigDecimal进行计算时应该是可以过的,但还是WA了,所以我觉得应该对知识点有更加明确的考察,若考察浮点数则可以给出提示该题测试点的设计是用double还是float,不应该让我们去猜测这种问题,对于出现这种的调试十分困难,非常浪费我们的时间
  • 2.个人意见,在上课结束之后,老师可以把记事本上面的txt文本发给我们,便于我们去进行复习,回放是好东西,但是如果只是单个知识点未理解,个人觉得看文档比看视频花费的时间要少,并且也可以锻炼我们的自学能力,由于老师讲课的时候知识点跳跃性很大,所以我觉得课后将记事本上的内容拷贝一份给我们是有必要的,上课的时候好好听,下课后再进行笔记的记录,可以做到提高上课的效率,同时可以有课后复习的效果。
这篇关于Java学习第一次记录的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!