модифицировать метод after в классе календаря, чтобы он возвращал true, когда больше, чем равно, а не строго больше - PullRequest
1 голос
/ 28 марта 2020
import java.util.Calendar;
import java.util.Date;

public class exercise4 {
    public static void main (String[] args) throws InterruptedException {
    Calendar cal1 = new CalendarSubclass();
    cal1.setTime(new Date());
    Thread.sleep(1000);
    Calendar cal2 = new CalendarSubclass();
    cal2.setTime(new Date());
    System.out.println(cal2.after(cal1));
    System.out.println(cal1.after(cal2));
    System.out.println(cal1.after(cal1));
    System.out.println(cal2.after(cal2));
    }
}

class CalendarSubclass extends Calendar {
    @Override
    public boolean after(Object when) {
        if (when instanceof Calendar && super.compareTo((Calendar) when) == 0) {
        //if (when instanceof Calendar && ((Calendar) when).toString().equals(this.toString())) {
        //if (when instanceof Calendar && equals((Calendar) when)) {        
        //          System.out.println("lala");
            return true;
        }
        return super.after(when);
    }
@Override
public int compareTo(Calendar anotherCalendar) {
    return compareDays(this.getFirstDayOfWeek(), anotherCalendar.getFirstDayOfWeek());
}

private int compareDays(int currentFirstDayOfWeek, int anotherFirstDayOfWeek) {
    return (currentFirstDayOfWeek > anotherFirstDayOfWeek) ? 1
            : (currentFirstDayOfWeek == anotherFirstDayOfWeek) ? 0 : -1;
}

}

Вывод:

false, false, true, true 

, но должен быть

true, false, true, true 

, поскольку я переопределил метод after с помощью CalenderSubclass.

Редактировать: Когда я удалил метод CompareTo и compareDays, он работает, но мне разрешено изменять только метод after!

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Три предложения:

  1. Используйте классы из java .time, современный Java API даты и времени и только те. Не используйте Calendar. Этот класс плохо спроектирован и давно устарел.
  2. Создайте для этого вспомогательный метод вместо использования подклассов.
  3. Дайте вашему служебному методу имя, которое будет четко отличать его от after метода Calendar. Называя его after, многие программисты будут думать, что он имеет ту же семантику, что и существующий метод after, то есть строго после. Вы рискуете запутаться.

Так, например:

public static boolean isBeforeOrOn(Instant i1, Instant i2) {
    return ! i1.isAfter(i2);
}

public static boolean isOnOrAfter(Instant i1, Instant i2) {
    return ! i1.isBefore(i2);
}

Давайте попробуем их:

    Instant i1 = Instant.now();
    Instant i2 = i1.plusSeconds(1);
    System.out.println("i2 is on or after i1? " + isOnOrAfter(i2, i1));
    System.out.println("i1 is on or after i2? " + isOnOrAfter(i1, i2));
    System.out.println("i1 is on or after i1? " + isOnOrAfter(i1, i1));
    System.out.println("i1 is before or on i2? " + isBeforeOrOn(i1, i2));
    System.out.println("i2 is before or on i2? " + isBeforeOrOn(i2, i2));

Вывод:

i2 is on or after i1? true
i1 is on or after i2? false
i1 is on or after i1? true
i1 is before or on i2? true
i2 is before or on i2? true

Ссылка: Oracle учебник: Дата Время объяснение, как использовать java .time.

0 голосов
/ 28 марта 2020

С вашим обновлением я вижу причину проблемы:

Переопределенная compareTo(Calendar anotherCalendar) является недопустимой реализацией для метода Calendar.compareTo. Документация для метода Calendar.compareTo() гласит:

Сравнивает значения времени [..], представленные двумя объектами Календаря.

Но Метод переопределения явно делает что-то еще (он сравнивает поле «firstDayOfWeek», которое имеет смысл только для Calendar экземпляров, настроенных для разных локалей.)

Если вы можете: убегайте и ищите укрытие от такого испорченного кода!


Если вы не можете: переопределите то, что делает метод оригинальных календарей compareTo:

@Override
public boolean after(Object when) {
    if (when instanceof Calendar) {
        Calendar other = (Calendar) when;
        return getTimeInMillis() >= other.getTimeInMillis();
    }
    return super.after(when);
}
...