Java基本功练习三中介绍了方法的抽象,为了更好的理解和强化,本篇博文再举几例进行训练。
方法的抽象这一程序开发设计的思想一定要多加练习,形成潜意识,以后在main方法中多写几句就会忍不住想要用方法来实现,这样开发的代码有很好的重用性。
示例一:显示程序运行的当前时间。(本例使用消息对话框的方式显示输出的)
运行效果如右图所示:
提示:我们知道Java中系统类可以返回从1970年1月1日到当前时间的毫秒数,本例就是从这点出发的。参照《Java基本功练习三》中的设计思路,请童鞋们自己设计。
以下是实现的源代码:
package Blog; import javax.swing.JOptionPane; public class blogTryProject { //显示当前的时间,北京时间 public static void main(String[]args){ String currentTime = printBeJingTime(); JOptionPane.showMessageDialog(null, currentTime,"显示当前的北京时间" ,JOptionPane.INFORMATION_MESSAGE); } //打印北京时间 public static String printBeJingTime(){ long totalMilliSeconds = System.currentTimeMillis(); long totalSeconds = totalMilliSeconds / 1000; long currentSecond = totalSeconds % 60; long totalMinutes = totalSeconds / 60; long currentMinute = totalMinutes % 60; long totalHours = totalMinutes / 60; long currentHour = totalHours % 24; long totalDays = totalHours / 24; long GMT = 8;//北京时间比格林尼治时间快8小时,位于东8时区 long BeJingCurrentHour = (currentHour + GMT) % 24; String BeJingTime = ""; String YearMonthDay = yearMonthDay(totalDays);//得到年月日 BeJingTime += YearMonthDay+"\n"; BeJingTime = BeJingTime +/*"当前是北京时间:"*/" "+BeJingCurrentHour+":"+ currentMinute+":"+currentSecond+"\n\nDesigned by : HarryKate\n"+"Time:2014/12/4"; return BeJingTime; } //得到当前时间的年月日 public static String yearMonthDay(long totalDays){ totalDays += 1;//与格林尼治时间相差一天,补回来 String YearMonthDay = ""; int yearCount = 1970;//年份计数 while(totalDays > 366 || totalDays >=365){ if(isLeapYear(yearCount)) totalDays -= 366; else totalDays -= 365; yearCount++; } int monthCount = 1;//月份计数 while(totalDays >= 28 || totalDays >=29 || totalDays >= 30 || totalDays > 31){ totalDays -= daysInMonth(monthCount,yearCount); monthCount++; } YearMonthDay = yearCount+"年"+monthCount+"月"+totalDays+"日"; return YearMonthDay; } //得到某月的天数 public static int daysInMonth(int monthCount,int yearCount){ if(monthCount == 1 || monthCount == 3 || monthCount == 5 || monthCount == 7 || monthCount == 8 || monthCount == 10 || monthCount == 12) return 31; else if(monthCount == 4 || monthCount == 6 || monthCount == 9 || monthCount == 11) return 30; else return isLeapYear(yearCount) ? 29 :28; } //判断是否是闰年 public static boolean isLeapYear(int yearCount){ return yearCount % 400 == 0||(yearCount % 4 == 0 && yearCount % 100 != 0); } }示例二:(要求)用户输入一个long型整数的信用卡号,显示这个卡是否合法,并判断出属于哪一类卡。注意:不能使用数组,只能使用基本的数据类型来实现。
假如信用卡遵循以下的模式:一个信用卡必须是13位到16位的整数,它的开头必须是:4,指Visa卡;5,Master卡;37,指American Express卡;6,指Discover卡。而其数字遵循的规律(为了叙述方便举例说明)。
假如卡号为:3788586118412,它必须遵循以下几点:
1)从右到做对每个数字翻倍。如果对某个数字翻倍之后的结果是一个两位数,那么就将这个两位数加在一起得到一位数。如8*2 = 16(1+6=7);3*2 = 6;5*2=10(1+0=1)
2)现将第一步得到的所有一位数相加。(6+5+7+7+1+7+3+2+2+7+8+2+4=71)
3)将卡号里从右到左在奇数位上的所有数字相加。(3+8+5+6+1+4+2=29)
4)将第二步和第三步得到的结果相加。(71+29=100)
5)如果第四步得到结果能被10整除,那么卡号合法,否则非法。(100%10=0合法)
运行效果如右图所示:
为了给童鞋们锻炼的空间,本作者只写了判断13位或16位的程序,完善的工作留给童鞋们锻炼!实现的代码如下所示:
package Blog; import java.util.Scanner; public class blogTryProject { public static void main(String [] args){ Scanner input = new Scanner(System.in); System.out.println("请输入13位或16位信用卡号,如下是测试用例\n" + "e.g 16位:4388576018402621是合法的,而4388586018402626是非法的。 " + "\ne.g 13位:3788586118412是合法的,而3788576118412是非法的"); for(int i = 0;i < 4;i++){ System.out.print("第"+(i+1)+"次输入: "); long cardNumber = input.nextLong(); cardJudge(cardNumber); } } //判断卡的合法性和类别并输出结果 public static void cardJudge(long cardNumber){ String name = kindOfCard(cardNumber); if(name == "Invalid Card!") System.out.println("卡号为:"+cardNumber+" 的卡是非法信用卡!\n"); else System.out.println("卡号为:"+cardNumber+" 的卡是合法的信用卡," + "卡的类型为: "+name+"\n"); } //判断卡的类型 public static String kindOfCard(long cardNumber){ String name = "Invalid Card!"; int countWeiShu = 0; long numberForWeiShu = cardNumber; while(numberForWeiShu != 0){ countWeiShu++; numberForWeiShu /= 10; } if(countWeiShu == 13 || countWeiShu == 16){ if(isLegalLaw(cardNumber)){ if(countWeiShu == 13) name = kindOfCard13(cardNumber); else name = kindOfCard16(cardNumber); } } return name; } //判断13位卡的类型 public static String kindOfCard13(long cardNumber) { String name = ""; long numberForKindOfCard = cardNumber; int countKindOfCard = 1; long lastNumber = 0; while (numberForKindOfCard != 0) { long number = 0; number = numberForKindOfCard % 10; numberForKindOfCard /= 10; if (countKindOfCard == 12) { if (number == 7) { lastNumber = number; } } if (countKindOfCard == 13) { switch ((int) number) { case 3: if (lastNumber == 7) name = "American Express"; break; case 4: name = "Visa"; break; case 5: name = "Master"; break; case 6: name = "Discover"; break; } } countKindOfCard++; } return name; } //判断16位卡的类型 public static String kindOfCard16(long cardNumber) { String name = ""; long numberForKindOfCard = cardNumber; long countKindOfCard = 1; long lastNumber = 0; while (numberForKindOfCard != 0) { long number = 0; number = numberForKindOfCard % 10; numberForKindOfCard /= 10; if (countKindOfCard == 15) { if (number == 7) { lastNumber = number; } } if (countKindOfCard == 16) { switch ((int) number) { case 3: if (lastNumber == 7) name = "American Express"; break; case 4: name = "Visa"; break; case 5: name = "Master"; break; case 6: name = "Discover"; break; } } countKindOfCard++; } return name; } //判断卡是否符合几条规则的限制 public static boolean isLegalLaw(long cardNumber) { long sumOfEachNumber = eachNumber(cardNumber); long sumOfOddNumber = oddNumber(cardNumber); long sumOfEachNumbrAndOddNumber = sumOfEachNumber + sumOfOddNumber; if (sumOfEachNumbrAndOddNumber % 10 == 0) return true; else return false; } //计算卡的每一位数字之和 public static long eachNumber(long cardNumber){ long sumOfEachNumber = 0; while(cardNumber != 0){ long number = 0; number = cardNumber % 10; cardNumber /= 10; number *= 2; if(number < 10) sumOfEachNumber += number; else{ sumOfEachNumber += number % 10; sumOfEachNumber += number / 10; } } return sumOfEachNumber; } //计算卡的奇数位的和 public static long oddNumber(long cardNumber){ int oddEvenCount = 1; long sumOfOdd = 0; long number = 0; while(cardNumber != 0){ number = cardNumber % 10; cardNumber /= 10; if(oddEvenCount % 2 == 1) sumOfOdd += number; oddEvenCount++; } return sumOfOdd; } }示例三:掷骰子游戏(相对基础,可以练练手)。掷两个骰子,每个骰子六面表示值为:1,2,3,4,5,6。检查两个骰子的和。1)如果和为2、3或12,你就输了;2)如果和是7或11,你就赢了;3)如果和是其他数,就确定了一个点。继续掷出一个7或掷出和刚才相同的点数。如果掷出7,你就输了,如果和刚才的点数一样,你就赢了。用程序扮演一个独立的玩家。
运行效果如下图所示(四种情况下的运行结果):
实现的源代码如下所示:
package XiTi5; public class XiTi { public static void main(String[]args){ while(true){ int num1 = (int)(Math.random()*6+1); int num2 = (int)(Math.random()*6+1); int sum = num1 + num2; if(sum == 2 || sum == 3 || sum == 12){ System.out.println("You rolled "+num1+" + "+num2+" = "+sum +"\nYou Lose!"); break; } else if(sum == 7 || sum == 11){ System.out.println("You rolled "+num1+" + "+num2+" = "+sum +"\nYou Win!"); break; } else{ int sumLast = sum; System.out.println("The first time you rolled "+num1+" + " +num2+" = "+sum); System.out.println("You must roll "+sum+",or your will lose!"); while(true){ num1 = (int)(Math.random()*6+1); num2 = (int)(Math.random()*6+1); sum = num1 + num2; if(sum == sumLast){ System.out.println("You rolled "+num1+" + "+num2+" = "+sum +"\nYou Win!"); break; } if(sum == 7){ System.out.println("You rolled "+num1+" + "+num2+" = "+sum +"\nYou Lose!"); break; } System.out.println("You rolled "+num1+" + "+num2+" = "+sum); } break; } } } }总结: 一定要自己先设计调试看看,思路很简单,但思路只是方案,要将方案转换成程序化的语言也是需要功夫的,切记!
另外调试第二题的时候由于之前用了太多的if语句,以至于后来大括号太多而影响调试,总是有错,就反复更改,后来发现更改时不小心删了个大括号,所以一定要排版规范。方法是:选中代码,右键选择Source-->Format进行调整,以方便调试。