我的方法有效,因为我只想知道多年来的差异,我的问题是我这样做效率很低。我觉得有一种更简单,更美观的方式来编写方法。
编辑:我必须编写自己的方法。我也不喜欢不用自己的方式使用高级的东西,这是第一年程序员的范畴。
public int differenceInYears(MyDate comparedDate) {
int difference = 0;
if (this.year > comparedDate.year) {
if (this.month > comparedDate.month) {
difference = this.year - comparedDate.year;
}
else if (this.month == comparedDate.month) {
if (this.day >= comparedDate.day) {
difference = this.year - comparedDate.year;
}
else {
difference = this.year - comparedDate.year - 1;
}
}
else {
difference = this.year - comparedDate.year - 1;
}
}
if (comparedDate.year > this.year) {
if (comparedDate.month > this.month) {
difference = comparedDate.year - this.year;
}
else if (comparedDate.month == this.month) {
if (comparedDate.day >= this.day) {
difference = comparedDate.year - this.year;
}
else {
difference = comparedDate.year - this.year - 1;
}
}
else {
difference = comparedDate.year - this.year - 1;
}
}
return difference;
}
我将在下面添加MyDate
类用于上下文:
public class MyDate {
private int day;
private int month;
private int year;
public MyDate(int day, int montd, int year) {
this.day = day;
this.month = montd;
this.year = year;
}
public String toString() {
return this.day + "." + this.month + "." + this.year;
}
public boolean earlier(MyDate compared) {
if (this.year < compared.year) {
return true;
}
if (this.year == compared.year && this.month < compared.month) {
return true;
}
if (this.year == compared.year && this.month == compared.month
&& this.day < compared.day) {
return true;
}
return false;
}
答案 0 :(得分:3)
我会假设您的方法正常工作。怎么改进?您可以做的第一件事是消除所有重复的this.year - comparedDate.year
和comparedDate.year - this.year
计算。无论如何,你都可以使用它们,所以让它们放在各自if
块的顶部。
public int differenceInYears(MyDate comparedDate) {
int difference;
if (this.year > comparedDate.year) {
difference = this.year - comparedDate.year;
if (this.month > comparedDate.month) {
}
else if (this.month == comparedDate.month) {
if (this.day >= comparedDate.day) {
}
else {
difference -= 1;
}
}
else {
difference -= 1;
}
}
if (comparedDate.year > this.year) {
difference = comparedDate.year - this.year;
if (comparedDate.month > this.month) {
}
else if (comparedDate.month == this.month) {
if (comparedDate.day >= this.day) {
}
else {
difference -= 1;
}
}
else {
difference -= 1;
}
}
return difference;
}
接下来,让我们摆脱那些空枝。
public int differenceInYears(MyDate comparedDate) {
int difference;
if (this.year > comparedDate.year) {
difference = this.year - comparedDate.year;
if (this.month == comparedDate.month) {
if (this.day < comparedDate.day) {
difference -= 1;
}
}
else if (this.month < comparedDate.month) {
difference -= 1;
}
}
if (comparedDate.year > this.year) {
difference = comparedDate.year - this.year;
if (comparedDate.month == this.month) {
if (comparedDate.day < this.day) {
difference -= 1;
}
}
else if (comparedDate.month < this.month) {
difference -= 1;
}
}
return difference;
}
现在让我们看看我们是否可以将&&
和||
的某些条件挤压在一起。
public int differenceInYears(MyDate comparedDate) {
int difference;
if (this.year > comparedDate.year) {
difference = this.year - comparedDate.year;
if (this.month == comparedDate.month && this.day < comparedDate.day ||
this.month < comparedDate.month)
{
difference -= 1;
}
}
if (comparedDate.year > this.year) {
difference = comparedDate.year - this.year;
if (comparedDate.month == this.month && comparedDate.day < this.day ||
comparedDate.month < this.month)
{
difference -= 1;
}
}
return difference;
}
这两个街区看起来非常相似,不是吗?我们可以通过有条件地交换this
和comparedDate
来合并它们。让a
和b
分别为更早和更晚的日期。
public int differenceInYears(MyDate comparedDate) {
MyDate a = (this.year < comparedDate.year) ? this : comparedDate;
MyDate b = (this.year < comparedDate.year) ? comparedDate : this;
int difference = b.year - a.year;
if (a.year < b.year) {
if (a.month == b.month && a.day < b.day ||
a.month < b.month)
{
difference -= 1;
}
}
return difference;
}
最后一次挤压。
public int differenceInYears(MyDate comparedDate) {
MyDate a = (this.year < comparedDate.year) ? this : comparedDate;
MyDate b = (this.year < comparedDate.year) ? comparedDate : this;
int difference = b.year - a.year;
if (a.year < b.year &&
(a.month == b.month && a.day < b.day ||
a.month < b.month))
{
difference -= 1;
}
return difference;
}
答案 1 :(得分:1)
好的,经过一番考虑,我觉得这看起来可能更好一些:
public int differenceInYears(MyDate comparedDate){
//Calculate days total
long daysTotalThisDate = this.year * 365 + this.month * 30 + this.day;
long daysTotalComparedDate = comparedDate.year * 365 + comparedDate.month * 30 + comparedDate.day;
//Get absolute value
long differenceInDays = daysTotalThisDate - daysTotalComparedDate;
if (differenceInDays < 0){
differenceInDays *= -1;
}
//the (int) cast will always round down, so anything under 365 will be 0
return (int) differenceInDays / 365;
}
这不考虑闰年。
在人们认为我对daysTotal...
的计算错误之前。你是对的。但是我对两次计算都做错了,所以考虑到我们只需要计算年份而不是几天的差异,最终结果仍然可以。
答案 2 :(得分:0)
这里的关键点是:有时&#34;复杂&#34;计算是必需的。
从这个意义上说:不要担心效率低下。你应该把时间花在尝试编写真正可读的代码上;非常像约翰的答案指导你。一般来说,您会将原则视为&#34; single layer of abstraction&#34;例如原则;避免这种冗长的if / else级联。
另一个关键点:此类作业完美用于单元测试。换句话说:你应该首先编写一些简单的测试用例,只需用各种(预先选择的)输入日期调用你的方法;然后检查是否返回了预期的结果。
换句话说:
您首先专注于编写许多测试用例,您可以确定您的实现是正确的...因为这使您能够重构您的代码而不是害怕打破它。
使用JUnit非常简单:
@Test
public testDifferenceIs0 {
MyDate thisYear = new MyDate(1,1,2017);
MyDate thisYearToo = new MyDate(1,1,2017);
assertThat(thisYear.differenceInYears(thisYearToo), is(0));
}
例如。