编程语言
首页 > 编程语言> > Java第一次随笔

Java第一次随笔

作者:互联网

经过两个月对于Java语言的学习,我认为有必要总结一下学习成果。下面是我近期学习的内容和对题目集的理解,以及对测试点的踩坑心得。

在学习Java语言的初期,在我看来Java语言的基本语法和C语言差不多,Java语言和C语言在很多方面的语法很相似,比如说循环语句,条件语句等。但是Java语言和C语言也有着不一样的地方,比如说在输入和输出是,c的输入方法是调用scanf()在括号中输入内容完成对变量的赋值,c的输出方法是调用printf(),在括号里面输入%d,%f,%c,%s等来输出整数型数字,浮点数,字符以及字符串等。尤其要注意的是,c在输入和输出的过程中要特别在逗号后面声明变量的地址,否则语法上不通过。在Java语言中您可以简单地使用System.out.println(); 或System.out.print(); 或System.out.print()将输出发送到标准输出(屏幕)。

示例:

class Main {

    public static void main(String[] args) {

    

        System.out.println("Java programming is interesting.");   

    }

}

关于println(),print()和printf()之间的区别

 

print() - 它在引号内打印字符串。

println() - 它在引号内打印字符串,类似于print()方法,相当于在print() 方法中加入了一个换行符。

printf() -格式化输出括号中的内容,于C中的printf()方法相似。

  Java中的输入方法和C有很大的区别,首先Java语言输入之前要先加入一个包,import java.util.Scanner;来使我们可以创建Scanner对象,

        Scanner input=new Scanner(System.in);

在创建完对象之后我们可以进行输入。

        Int a=input.nextInt();

        double a=input.nextDouble();

示例:

public class Main{

    public static void main(String[] args){

        Scanner input = new Scanner(System.in);

        System.out.println(“请输入一个整数”)

        int x=input.nextInt();

System.out.println(“您输入的整数为”+x);

    }

}

需要注意的是在输入不同类型的数据时要采用不同的输入类型,输入浮点数是采用input.nextFloat或者input.nextDouble。输入字符类型时可以用Input.next()或者Input.nextLine()。

 

在学习面向对象的过程中,对象的创建对我认知的冲击比较大,我们在创建对象的时候要考虑的两个方面:对象的属性和方法。这样说比较晦涩难懂,我举一个简单的例子,假如我们现在要创建一个“学生”的类,那么这个学生类里面应该要包括这个学生的学号,姓名等,这些称之为属性。学生要运动,要吃饭,要回答问题,这些学生的行为我们称之为方法。也就是说在对象中对象的基本信息就是属性,对象的行为称之为方法。

我们知道Java语言是面向对象的程序设计,其包括了三大基本要素:封装,继承以及多态。下面我来简单介绍一下这三个特征。

首先关于封装性,我们都知道在c语言中有一个神奇的东西叫做指针,它里面承载了内存地址,我们可以通过指针来便捷的访问和更改某一处数据,但是这就存在了一定的安全隐患。我们可以想一下,如果任何人都可以随意的更改数据,那么这个程序一定是不安全的。于是在Java语言设计时就有了这么一种性质,封装性。

    在面向对象程序设计的过程中,我们要创建对象,在对象内部我们引用关键词private来对属性进行封装,private的意思是私有的,也就是说在对象外部,我们并不能直接访问这个属性,而是要通过对象内部的方法来进行访问或是更改。

例如:

class Year{

    private int y;

    public Year(int y) {

        this.y = y;

    }

    public Year() {

    }

    public int getY() {

        return y;

    }

}

我们用年份举例,上面我们有一个类表示年。在这个类之中我们的y属性是私有的,于是在对象外部我们就不能直接访问这个属性,而是要通过get和set方法来进行访问或更改。

其次关于继承,继承的关键词为extends。其中包括子类和父类。子类又可以称为派生类。父类又可以称为超类(Super Class),要注意的是在Java语言中只能实现单继承,就是说一个类只能有一个父类。

我们举一个继承的例子:

class Person{//父类

private String name;

private int age;

public void setName(String name){

this.name=name;

}

public void setAge(int age){

this.age=age;

}

public String getName(){

return this.name;

}

public int getAge(){

return this.age;

}

}

class Student extends Person{            //Student类继承了Person类

private String school;               //子类扩充属性

                                     //子类扩充方法

public void setSchool(String school){

this.school=school;

}

public String getSchool(){

return this.school;

}

}

在上面的例子中我们有一个Person类,Student类继承了Person类,同时也代表这Student类继承了Person类中public方法(注意私有的属性是无法继承的)。

要注意的是当子类方法和父类方法名字一样时,子类中的方法会覆盖父类中的方法,称之为方法的重载。

最后关于多态,多态中涉及到的几个概念,向上转型和向下转型,向上转型。是子类型转到父类型,向下转型是父类型转到子类型,无论是向上转型还是向下转型,两种类型之间必须有继承关系,否则编译器无法通过。下面举个动物类的例子

Class Animal{

Public void move(){

System.out.print(“动物在移动”)

}

}

Class Cat extend Animal {

Public void move(){

System.out.print(“猫在走猫步”)

}

}

Class Bird extend Animal {

Public void move(){

System.out.print(“鸟在飞”)

}

}

以下语句是正确的

Animal a = new Cat();

只是一个向上转型的例子,Animal和Cat存在继承关系。 Java中存在这样的语法,父类型的引用指向子类型的对象。

1. Java程序永远都分为编译阶段和运行阶段。

2.先分析编译阶段,再分析运行阶段,编译阶段无法通过,则程序无法运行。

3.编译阶段编译器检查a这个引用的数据类型为Animal,由于animal class中move 这个方法,所以编译通过了。这个过程我们称之为静态绑定或者编译阶段绑定,只有静态绑定成功之后才有后续的运行。

4.在程序运行阶段。JVA对于内存当中真实创建的对象是cat对象。那么程序运行阶段一定会调用cat对象里的move方法。此时发生了程序的动态绑定即运行阶段绑定。

5.父类型引用指向子类型应用这种机制导致的程序。存在编译阶段和运行阶段两种不同的形态或状态。这种机制可以称为一种多态机制。

以上是前端时间对知识点的简单概阔,下面分析在习题中所遇到的问题

这是一个关于日期计算的问题

1.参考题目集二中和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:

public boolean checkInputValidity();//检测输入的年、月、日是否合法

public boolean isLeapYear(int year);//判断year是否为闰年

public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期

public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期

public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)

public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等

public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数

public String showDate();//以“year-month-day”格式返回日期值

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

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;
    int []a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};

    public DateUtil(DateUtil d){
        this.day = d.getDay();
        this.month = d.getMonth();
        this.year = d.getYear();
    }

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

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

    public int getDay() {
        return day;
    }

    public int getMonth() {
        return month;
    }

    public int getYear() {
        return year;
    }

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

    public void setYear(int year) {
        this.year = year;
    }
    public boolean checkInputValidity() {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year)){
            a[2]=29;
        }
        if(year>=1820&&year<=2020&&month>0&&month<=12&&day<=a[month]&&day>0){
            return true;
        }
        else
            return false;
    }
    public boolean isLeapYear(int year){
        if(( year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){
            return true;
        }
        else
            return false;
    }

    public DateUtil getNextNDays(int n){
        DateUtil newdate = new DateUtil(this);
        int[] a = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        int years=0;
        if(!isLeapYear(newdate.year)&&isLeapYear(newdate.year+1)&&newdate.getMonth()>2){
            n=n-366;
        }
        while(n>years){
            if(isLeapYear(newdate.year))
                years=366;
            else
                years=365;
            newdate.year++;
            n=n-years;
        }
        for (int i = 1; i <= n; i++) {
            newdate.day++;
            if(isLeapYear(newdate.year)) {
                a[2] = 29;
            }
            else {
                a[2] = 28;
            }
            if (newdate.day > a[newdate.month]) {
                newdate.day = 1;
                newdate.month++;
                if (newdate.month > 12) {
                    newdate.month = 1;
                    newdate.year++;
                }
            }
        }
        return  newdate;
    }

    public DateUtil getPreviousNDays(int n){
        DateUtil newdata = new DateUtil(this);
        while (n>=365) {
            if(isLeapYear(newdata.year)) {
                newdata.year = newdata.year - 1;
                n = n - 366;
            }
            if(!isLeapYear(newdata.year)) {
                newdata.year = newdata.year - 1;
                n = n - 365;
            }
        }
        for(int i = 0; i < n; i++){
            newdata.setDay(newdata.getDay() - 1);
            if(newdata.getDay() <= 0){
                newdata.setMonth(newdata.getMonth() - 1);
                if(newdata.getMonth() <= 0){
                    newdata.setMonth(12);
                    newdata.setYear(newdata.getYear() - 1);
                }
                if(isLeapYear(newdata.getYear()) && newdata.getMonth() == 2)
                    newdata.setDay(29);
                else
                    newdata.setDay(newdata.a[newdata.getMonth()]);
            }
        }
        return newdata;
    }


    public boolean compareDates(DateUtil date){
        if(year > date.getYear())
            return true;
        else if(year == date.getYear() && month > date.getMonth())
            return true;
        else if(year == date.getYear() && month == date.getMonth() && day > date.getDay())
            return true;
        return false;
    }
    public boolean equalTwoDates(DateUtil date){
        if(this.year != date.getYear())
            return false;
        else if(this.day != date.getDay())
            return false;
        else if(this.month != date.getMonth())
            return false;
        else
            return true;
    }

    public int getDaysofDates(DateUtil date){
        int x = 0;
        DateUtil newdata = new DateUtil(this);
        if(this.compareDates(date)){
            while(newdata.getYear() - date.getYear() >= 2){
                if(newdata.isLeapYear(newdata.getYear()) && newdata.getMonth() > 2)
                    x = x + 366;
                else if(newdata.isLeapYear(newdata.getYear() - 1) && newdata.getMonth() <= 2)
                    x = x + 366;
                else
                    x = x + 365;
                newdata.setYear(newdata.getYear() - 1);
            }
            while(true){
                if(newdata.equalTwoDates(date))
                    break;
                x++;
                newdata.setDay(newdata.getDay() - 1);
                if(newdata.getDay() <= 0){
                    newdata.setMonth(newdata.getMonth() - 1);
                    if(newdata.getMonth() <= 0){
                        newdata.setMonth(12);
                        newdata.setYear(newdata.getYear() - 1);
                    }
                    if(isLeapYear(newdata.getYear()) && newdata.getMonth() == 2)
                        newdata.setDay(29);
                    else
                        newdata.setDay(newdata.a[newdata.getMonth()]);
                }
            }
        }
        else{
            while(date.getYear() - newdata.getYear() >= 2){
                if(newdata.isLeapYear(newdata.getYear()) && newdata.getMonth() <= 2)
                    x = x + 366;
                else if(newdata.isLeapYear(newdata.getYear() + 1) && newdata.getMonth() > 2)
                    x = x + 366;
                else
                    x = x + 365;
                newdata.setYear(newdata.getYear() + 1);
            }
            while(true){
                if(newdata.equalTwoDates(date))
                    break;
                x++;
                newdata.setDay(newdata.getDay() + 1);
                if(isLeapYear(newdata.getYear()) && newdata.getMonth() == 2){
                    if(newdata.getDay() > 29){
                        newdata.setMonth(newdata.getMonth() + 1);
                        newdata.setDay(1);
                    }
                }
                else if(newdata.getDay() > newdata.a[newdata.getMonth()]){
                    newdata.setMonth(newdata.getMonth() + 1);
                    newdata.setDay(1);
                    if(newdata.getMonth() > 12){
                        newdata.setMonth(1);
                        newdata.setYear(newdata.getYear() + 1);
                    }
                }
            }
        }
        return x;
    }
    public String showDate(){
        return year + "-" + month + "-" + day;
    }
}

这是此题的源代码。

在写这道题的时候,我认为在计算日期前n天和后n天的时候很伤脑筋,在最开始我的思路是如果n大于365,就先一年一年的算,遇到润年就减去366,否则就减去365.但是在测试的时候遇到了一个问题。在测试这一组数据的时候1 1999 3 28 6543,输出结果应该是2017-2-24。最开始我的输出结果一直是2017-2-25,随后我注意到了一个问题,1999年是一个平年,但是2000年是一个闰年,而且我们是从1999年的3月28日开始算的,到了2000年的3月28日,我经历了366天而不是365天,这就是为什么结果比正确答案多算了一天。于是我们多加一种情况:如果今年是平年,但是下一年是闰年,而且我们是从今年的3月之后开始算的,那我们就应该减去366而不是365.

2.我们换一种想法,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

类的代码如下:

class Year{

    int value;

 

    public Year(){

    }

 

    public Year(int value){

        this.value=value;

    }

 

    public int getValue(){

        return value;

    }

 

    public void setValue(int value){

        this.value=value;

    }

 

    public  boolean isLeapYear(int value){

        if((value%4==0&&value%100!=0)||value%400==0)

            return true;

        else

            return false;

    }

    public  boolean isLeapYear(){

        if((value%4==0&&value%100!=0)||value%400==0)

            return true;

        else

            return false;

    }

 

    public boolean validate(){

        if(value<=2050&&value>=1900)

            return true;

        else

            return false;

    }

 

    public void yearIncrement(){

        value=value+1;

    }

 

    public void yearReduction(){

        value=value-1;

    }

}

 

class Month{

    int value;

    Year year;

 

    public Month(){

    }

 

    public Month(int yearValue,int monthValue){

        this.year=new Year(yearValue);

        this.value=monthValue;

    }

 

    public int getValue(){

        return value;

    }

    public Year getYear(){

        return year;

    }

 

    public void setValue(int value){

        this.value=value;

    }

    public void setYear(Year year){

        this.year=year;

    }

 

    public void resetMin(){

        value=1;

    }

 

    public void resetMax(){

        value=12;

    }

 

    public boolean validate(){

        if(value>=1&&value<=12)

            return true;

        else

            return false;

    }

 

    public void monthIncrement(){

        value=value+1;

    }

 

    public void monthReduction(){

        value=value-1;

    }

}

//Day类

class Day{

    int value;

    Month month;

    int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 

    public Day(){

    }

 

    public Day(int yearValue,int monthValue,int dayValue){

        this.month=new Month(yearValue,monthValue);

        this.value=dayValue;

    }

 

    public int getValue(){

        return value;

    }

    public Month getMonth(){

        return month;

    }

 

    public void setValue(int value){

        this.value=value;

    }

    public void setMonth(Month value){

        this.month=value;

    }

 

    public void resetMin(){

        value=1;

    }

 

    public void resetMax(){

        value=a[month.getValue()-1];

    }

 

    public boolean validate(){

        if(this.getMonth().getYear().isLeapYear())

            a[1]=29;

        if(value>=1&&value<=a[month.getValue()])

            return true;

        else

            return false;

    }

 

    public void dayIncrement() {

        value=value+1;

    }

 

    public void dayReduction() {

        value=value-1;

    }

}

我们将DateUtil类和Day类关联在一起Day类和Month类关联在一起,Month类和Year类关联在一起。这样我们知道了day就可以知道这一天的年份和月份。这是一个链式结构,彼此之间的耦合性很强,对于程序设计而言不够简洁,下面还有另外一种聚合。

3.类图如下:

 

 

 

在这个聚合之中,我们将年月日分开表示,这样做的好处是可以便捷的访问年月日,而不是像上次的聚合那样,必须要通过day才能访问其他属性,这次的聚合显然更加方便。类的代码如下:

class Year{

    private int y;

 

    public Year(int y) {

        this.y = y;

    }

 

    public Year() {

 

    }

 

    public int getY() {

        return y;

    }

 

    public void setY(int y) {

        this.y = y;

    }

    public void yearIncrement(){

        this.y++;

    }

    public void yearReduction(){

        this.y--;

    }

 

}

 

class Month{

    private int m;

 

    public Month(int m) {

        this.m = m;

    }

 

    public Month() {

    }

 

    public int getM() {

        return m;

    }

 

    public void setM(int m) {

        this.m = m;

    }

    public void monthIncrement(){

        this.m++;

    }

    public void monthReduction(){

        this.m--;

    }

    public void resetMin(){

        m=1;

    }

    public void resetMax(){

        m=12;

    }

}

 

class Day {

    private int d;

 

    public Day(int d) {

        this.d = d;

    }

 

    public Day() {

    }

 

    public int getD() {

        return d;

    }

 

    public void setD(int d) {

        this.d = d;

    }

 

    public void dayIncrement() {

        this.d++;

    }

 

    public void dayReduction() {

        this.d--;

    }

}

这样分类,使得类之间的耦合度变得非常低,更加符合面向对象设计的初衷。

public class Main {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        //int year = 0;

        //int month = 0;

        //int day = 0;

        Year year=new Year(0);

        Month month = new Month(0);

        Day day = new Day(0);

 

        int choice = input.nextInt();

 

        if (choice == 1) { // test getNextNDays method

            int m = 0;

            year.setY(Integer.parseInt(input.next()));

            month.setM(Integer.parseInt(input.next()));

            day.setD(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().getY() + "-" + date.getMonth().getM() + "-" + date.getDay().getD() + " next " + m + " days is:");

            System.out.println(date.getNextNDays(m).showDate());

        } else if (choice == 2) { // test getPreviousNDays method

            int n = 0;

            year.setY(Integer.parseInt(input.next()));

            month.setM(Integer.parseInt(input.next()));

            day.setD(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().getY() + "-" + date.getMonth().getM() + "-" + date.getDay().getD() + " previous " + n + " days is:");

            System.out.println(date.getPreviousNDays(n).showDate());

        } else if (choice == 3) {    //test getDaysofDates method

            year.setY(Integer.parseInt(input.next()));

            month.setM(Integer.parseInt(input.next()));

            day.setD(Integer.parseInt(input.next()));

 

            Year anotherYear = new Year(Integer.parseInt(input.next()));

            Month anotherMonth =  new Month(Integer.parseInt(input.next()));

            Day anotherDay = new Day(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);

        }

    }

}

在这个主函数中,我改变了输入方式,没有直接对int型的变量赋值,而是先创建对象再通过set函数对对象内部的属性进行赋值,这是利用了Java语言的封装性,在创建对象的时候采用构造方法传入三个对象比如DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);其他算法与题目一一样,只是要将所有的变量用引用的方式替换。

总结:在学习Java的语法时,Java的语法是类似c语言的,所以学习的比较轻松。唯一需要注意的是有几个不容易搞清楚的关键字的用法,public,protected,private,static,在学习Java的面向对象的编程语言的特性。比如继承,构造器,抽象类,接口,方法的多态,重载,覆盖,Java的异常处理机制。对于一个没有面向对象语言背景的人来说,我觉得这个过程需要花很长很长时间,因为学习Java之前没有C++的经验,只有C语言的经验,花了很长时间,才彻底把这些概念都搞清楚,把书上面的例子反复的揣摩,修改,尝试,把那几章内容反复的看过来,看过去,看了很多遍,才领悟了。在之后的学习中,我认为还是要巩固基础知识,只有基础知识学明白才能更好的学习Java语言。

标签:Java,int,System,第一次,newdata,year,date,随笔,public
来源: https://www.cnblogs.com/zhaoziyiblog/p/16123419.html