首先分析问题,通过年月得到当前月份的天数,按照生活中的惯性,就是分析年份,后分析月份,这里我要说不,虽然这样同样可以算出结果,速度上也与先判断月份相差毫微,虽然这个时间短的可以忽略不计,但是作为一个有情怀的程序员,对代码的要求就是要短小精悍,能省就省,我先列出两种分析方式的算法代码,当然这种写法是最笨重的,这里主要是为了突出问题,优化一步步来,我始终强调,先分析问题,只要会写代码的程序员写完立马就会改为方式二的写法,因为在代码量上很直观,一眼就能看的清楚:
先判断年份的写法:
public static int getCurrentMonthDays1(int year,int month){ if (year%4==0){ switch (month){ case 1: return 31; case 2: return 29; case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; default: return 0; } }else { switch (month){ case 1: return 31; case 2: return 28; case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; default: return 0; } } }
先判断月份的写法:
public static int getCurrentMonthDays2(int year, int month) { switch (month) { case 1: return 31; case 2: if (year%4==0){ return 29; }else { return 28; } case 3: return 31; case 4: return 30; case 5: return 31; case 6: return 30; case 7: return 31; case 8: return 31; case 9: return 30; case 10: return 31; case 11: return 30; case 12: return 31; default: return 0; } }
明显,代码的量上面有很大变化,性能上呢,方法一就不如方法二了,在判断2月份的天数的时候i,两个方法的耗时是一样的,因为都经过了两次判断,但是,如果判断其它月份,方法一就不如方法二了,每次都会多判断一个year%4==0,因为平年和闰年除了2月份不一样,其它月份都一致,所以得到其它月份的天数的时候,还要判断年份就等于脱裤子放屁,多此一举,话糙理不糙,到这里,其实还只是开始,我们来分析代码中的共同点,就是1、3、5、7、8、10、12月都是31天,4、6、9、11月都是30天,这样又有共同点,我们可以简化一下代码了,这次只是代码减少了,速度上与方法2也没有什么差距
方法3:
public static int getCurrentMonthDays3(int year, int month) { if (month == 1 ||month == 3 ||month == 5 ||month == 7 ||month == 8 ||month == 10 ||month == 12 ){ return 31; }else if (month==2){ return year%4==0?29:28; } return 30; }
这样以来,瞬间清爽了好多,不过还不够,我们还要再优化,很明显看到天数为31天的月份有7个,30天的有4个,2月份有一个,计算问题,先易后难,道理很浅显,我们判断2月份的天数经过两个判断就可以ok,判断是否是大月,要经过最少1个判断,最多7个判断才能知道,同理,判断小月最少1个,最多4个判断,综合考虑,判断二月份的条件放在最前面,判断是否是小月放在中间,最后的大月就不用判断了,也就是三个大的范围条件换一下位置,性能会有提升:
方法4:
public static int getCurrentMonthDays4(int year, int month) { if (month == 2) { return year%4==0?29:28; } else if (month == 4 || month == 6 || month == 9 || month == 11) { return 30; } return 31; }
说了这里,会陷入一种空口说大话的尴尬境地,你说快就快,你说性能高就高?拿出凭据来,好吧,服不服,不服来跑个分
public static void main(String[] args) { long a = System.nanoTime(); for (int j=0;j<=Integer.MAX_VALUE/2;j++){ for (int i = 1; i < 13; i++) { getCurrentMonthDays4(2016, i);//测试方法3的时候对应换成方法3 } for (int i = 1; i < 13; i++) { getCurrentMonthDays4(2015, i);//测试方法3的时候对应换成方法3 } } System.out.println(System.nanoTime()-a); }
通过这种虐CPU的方式来得到多次测试的时间,本来用的j<=Integer.MAX_VALUE的条件,奈何我的电脑CPU不够强劲,减去一半,平年闰年都弄进去多次运行,最终,方法3的纳秒数在5518968到7031239之间徘徊,方法4的纳秒数在4822850和5222850之间徘徊,这个时间会受硬件影响,不过我多次测试,就是大约在这个区间内,如果你们的电脑CPU好点,这个时间会相对短一点
,不过,从这个大致结果,就已经很能说明问题了,大家可以去试试。这个东西确实简单, 所以高手勿笑,献丑了,在家闲的无聊随便写的。