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进行调整,以方便调试。