JavaSE自学笔记(8)

这篇博客介绍了如何在Java中创建一个日期类,并实现了日期的合法校验、相减计算相差天数的功能。此外,还展示了如何构建时间类、日期时间类,并提供了日期和时间的前后推进操作。最后,文章详细解释了如何运用二分查找算法在一个二维数组中查找目标值,并给出了完整的代码实现。
摘要由CSDN通过智能技术生成

1.计算年月日相差多少天

public class MyDate {
    public int year;
    public int month;
    public int day;

    // 1. 必须得校验,传入参数的合法性
    //    year: 1900 <= year <= 3000
    //    month: 1 <= month <= 12
    //    day:   1 <= day <= 每个月的天数
    // 2. 如果不符合,应该怎么办 —— 由甲方和乙方共同协商出结果
    //    1. 抛异常,通知对方出错(我们选用这种)
    //    2. 尝试修复参数
    public MyDate(int year, int month, int day) {
        if (year < 1900 || year > 3000) {
            // 完全就是一个实例化对象的代码
            RuntimeException exception = new RuntimeException("year 参数错误");
            // 通过 throw 关键字,抛出了一个异常对象
            throw exception;
        }

        if (month < 1 || month > 12) {
            throw new RuntimeException("month 参数错误");
        }

        // 需要一个,可以根据 year, month,计算出该月共有多少天的方法
        if (day < 1 || day > getMonthDay(year, month)) {
            throw new RuntimeException("day 参数错误");
        }

        this.year = year;
        this.month = month;
        this.day = day;
    }

    public MyDate(MyDate from) {
        this.year = from.year;
        this.month = from.month;
        this.day = from.day;
    }

    public int getMonthDay(int year, int month) {
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                // 利用不加 break,代码会继续向下的规则
                return 31;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            case 2:
                return isLeapYear(year) ? 29 : 28;
            default:
                // 肯定不会走到这里,但 Java 语法要求所有分支必须有返回值
                // 所以写出来
                return -1;
        }
    }

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

    @Override
    public String toString() {
        String s = String.format("%04d-%02d-%02d", year, month, day);
        return s;
    }

    // 参数合法性校验:this 代表的日期 必须大于 from 代表的日期
    public int 计算相差天数(MyDate from) {
        // this 指向的对象
        // 和
        // from 指向的对象
        // 之间相差的天数


        // 要求 this 大于 from
        // if (from >= this) {  // 引用无法使用 >= 运算符
        // 所以使用人为规定出的 compareTo 方法,进行日期的大小比较
        if (this.compareTo(from) <= 0) {   // compareTo(from) <- 没有歧义时,可以省略 this
            throw new RuntimeException("from 的日期必须当前日期之前");
        }

        // 用 from 的复制计算,以免下面计算时,把别人传入的 from 对象修改掉
        MyDate fromCopy = new MyDate(from);
        //MyDate fromCopy = from;     // 只是让 fromCopy 指向 from 指向的对象了
                                    // 通过 fromCopy 修改对象,from 也感受的到 —— 引用的共享特性

        // while (from < this) {
        int count = 0;
        while (fromCopy.compareTo(this) < 0) {
            // 让 from 向后走一天
            // from.day++;     // 错误,没有考虑进位问题
            System.out.println(fromCopy);
            fromCopy.increment();

            count++;
        }

        return count;
    }

    public void increment() {
        day++;
        if (day <= getMonthDay(year, month)) {
            // day 不需要考虑进位
            return;
        }

        // day 需要考虑日期进位
        month++;
        day = 1;

        if (month <= 12) {
            // month 不需要考虑进位
            return;
        }

        year++;
        month = 1;
    }

    // 定义一个比较方法 (this, other)
    // 规定,如果 this < from,返回任意负数
    //       如果 this == from,返回 0
    //       如果 this > from,返回任意正数
    public int compareTo(MyDate from) {
        // this 和 from 在进行比较

        if (year != from.year) {
//            if (year > from.year) {
//                return 1;
//            } else {
//                return -1;
//            }
            return year - from.year;    // year > from.year => 正数;否则 负数
        }

        // 说明 year == from.year
        if (month != from.month) {
            return month - from.month;
        }

        // 说明 year == from.year && month == from.month
        return day - from.day;
    }
}

 

public class MyDateTest {
    public static void main(String[] args) {
        MyDate from = new MyDate(2024, 1, 1);

        MyDate to = new MyDate(2024, 3, 1);
//        System.out.println(to.compareTo(from));     // 正数  to > from
//        System.out.println(from.compareTo(to));     // 负数  from < to
//        System.out.println(to.compareTo(to));       // 0     to == to
//        System.out.println(from.compareTo(from));   // 0     from == from

        System.out.printf("从 %s 到 %s 经过了 %d 天\n",
                from, to, to.计算相差天数(from)
        );
    }
}

2.日期时间

package date_time;

public class MyDate {
    private int year;
    private int month;
    private int day;

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

    public MyDate(MyDate date){
        this.year = date.year;
        this.month = date.month;
        this.day = date.day;
    }

    public String toString(){
        return String.format("%d-%02d-%02d",year,month,day);
    }

    public void next(){
        day++;
        if(day<=getDayOfMonth(year,month)){
            return;
        }
        month++;
        day=1;
        if(month<=12){
            return;
        }
        year++;
        month=1;
    }

    public void previous(){
        day--;
        if(day>=1){
            return;
        }
        month--;
        if(month>=1){
            day = getDayOfMonth(year,month);
            return;
        }
        year--;
        month=12;
        day = getDayOfMonth(year,month);
    }

    private static void check(int year, int month, int day) {
        if(month<1 || month>12){
            throw new RuntimeException("月输入错误");
        }
        int days = getDayOfMonth(year,month);
        if(day<1 || day>days){
            throw new RuntimeException("日输入错误");
        }
    }

    private static final int[] DAYS = {31,28,31,30,31,30,31,31,30,31,30,31};
    private static int getDayOfMonth(int year, int month) {
        if (month==2&&isLeap(year)){
            return 29;
        }
        return DAYS[month-1];
    }

    private static boolean isLeap(int year) {
        return (year%4==0 && year%100!=0) || year%400==0;
    }
}
package date_time;

public class MyTime {
    private int hour;
    private int minute;
    private int second;

    public MyTime(int hour,int minute,int second){
        check(hour,minute,second);
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

    private static void check(int hour,int minute,int second){
        if (hour<0||hour>=24){
            throw new RuntimeException("时输入错误");
        }
        if(minute<0||minute>=60){
            throw new RuntimeException("分输入有误");
        }
        if (second<0||second>=60){
            throw new RuntimeException("秒输入有误");
        }
    }

    public MyTime(MyTime time){
        this.hour = time.hour;
        this.minute = time.minute;
        this.second = time.second;
    }

    @Override
    public String toString() {
        return String.format("%02d:%02d:%02d",hour,minute,second);
    }

    //表示是否到第二天
    public boolean next(){
        second++;
        if(second<60){
            return false;
        }
        minute++;
        second=0;
        if (minute<60){
            return false;
        }
        hour++;
        minute=0;
        if(hour<24){
            return false;
        }
        hour=0;
        return true;
    }

    public boolean previous(){
        second--;
        if(second>=0){
            return false;
        }
        minute--;
        second=59;
        if (minute>=0){
            return false;
        }
        hour--;
        minute=59;
        if (hour>=0){
            return false;
        }
        hour=23;
        return true;
    }
}
package date_time;

public class MyDateTime {
    private MyTime time;
    private MyDate date;

    public MyDateTime(MyDateTime datetime){
        this.date=new MyDate(datetime.date);
        this.time=new MyTime(datetime.time);
    }

    public MyDateTime(int year,int month,int day,int hour,int minute,int second){
        this.date = new MyDate(year, month, day);
        this.time = new MyTime(hour, minute, second);
    }

    @Override
    public String toString() {
        return String.format("%s %s",date,time);
    }

    public void next(){
        if(time.next()){
            date.next();
        }
    }

    public void previous(){
        if (time.previous()){
            date.previous();
        }
    }
}
package date_time;

import java.util.concurrent.TimeUnit;

public class test {
    public static void main(String[] args) throws InterruptedException {
        MyDateTime datetime = new MyDateTime(2021,12,31,23,59,55);


        while(true){
            System.out.println(datetime);
            datetime.next();
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

3.二分查找(二维数组)

package binary_search;

public class Search {
    public static int[] search(long[][] array,int rows,int columns,long target){
        Range range = new Range(array,rows,columns);

        while(range.size() > 0){
            long middleValue = range.getMiddleValue();
            if(target == middleValue){
                return range.getmiddleIndex();
            }else if (target < middleValue){
                range.discardRightPart();
            }else{
                range.discardLeftPart();
            }
        }
        return new int[]{-1,-1};
    }
}
package binary_search;

public class Range {
    private final long[][] array;
    private final int columns;
    private int lowRow;
    private int highRow;
    private int lowColumn;
    private int highColumn;

    public Range(long[][] array,int rows,int columns) {
        this.array = array;
        this.columns = columns;
        this.lowRow = 0;
        this.lowColumn = 0;
        this.highRow = rows - 1;
        this.highColumn = columns - 1;
    }


    public int size() {
        return (columns - lowColumn) + (highRow - lowRow - 1) * columns + (highColumn + 1);
    }


    public long getMiddleValue() {
        int[] index = getmiddleIndex();
        int row = index[0];
        int column = index[1];
        return array[row][column];
    }


    public int[] getmiddleIndex() {
        int halfSize = size() / 2;
        int middleRow = lowRow;
        int middleColumn = lowColumn;
        middleColumn += halfSize;

        while(middleColumn>=columns){
            middleRow++;
            middleColumn -= columns;
        }

        return new int[]{middleRow,middleColumn};
    }


    public void discardRightPart() {
        int[] index = getmiddleIndex();
        int row = index[0];
        int column = index[1];

        highRow = row;
        highColumn = column - 1;
        if(highColumn<0){
            highRow--;
            highColumn = columns - 1;
        }
    }


    public void discardLeftPart() {
        int[] index = getmiddleIndex();
        int row = index[0];
        int column = index[1];

        lowRow = row;
        lowColumn = column + 1;
        if (lowColumn >= columns){
            lowRow++;
            lowColumn = 0;
        }
    }
}
package binary_search;


import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        long[][] array = {
                {1,2,3,4,5},
                {6,7,8,9,10},
                {11,12,13,14,15}
        };
        int rows = 3;
        int columns = 5;

        for(long target = 0;target <= 16;target++){
            int[] index = Search.search(array,rows,columns,target);
            System.out.printf("查找%d的结果是:%s\n",target, Arrays.toString(index));
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值