小白学Java基础案例(一)

写在前面

  • 关于题目
    涉及Java语言基础、类与对象基础、类的设计与封装、类继承与接口的设计、集合框架与泛型、异常类、嵌套类、枚举类型、输入/输出流、多线程与网络编程基础等大内容,知识点包括标识符、关键字与字面值、变量与类型、运算符与表达式、语句、类与对象、Math类、字符串:String类与StringBuffer类、数组对象、包装类、大数处理与BigInteger类、时间处理、类设计的基本思路、矩形类的初步设计、类声明与域的定义……
    题目来自实验课老师布置,由于课本不在手边,所以涉及课本例题的,没有办法提供原例题。
  • 关于答案
    主要是我作业里自己写的代码,如果和老师发的参考答案差别较大,会发上两个答案。能力有限,如果有错误的地方,欢迎指正。
  • 持续更新中……

使用教材

  • Java面向对象程序设计

出版社:高等教育出版社
作者: 苏健
版次:1
重点项目: “十一五”国家规划课题研究成果

实验二:Java语言基础

  1. 结合C语言课程的代码,将例2.4更改为判断素数的总个数。
import java.util.Scanner;
public class sy2 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入若干个整数(以英文字符结束):");
		int count=0;
		while(scanner.hasNextInt()) {
			int n=scanner.nextInt();
			if(isSushu(n))
				count++;
		}
		System.out.println("一共输入了" +count+ "个素数");
	}
	
	static boolean isSushu(int n) {
		int j;
		for(j=2;j<n;j++) 
			if(n%j==0)
				return false;
		
		return true;
	}
}
  1. 阅读课本P32中2.5.2关于Java基本类型的内容。试回答:C语言中是否有对应的数据类型? 如果有,两者有差异吗,如果没有,C语言中有没有实现类似功能的内容?

Java基本类型在C语言中对应的基本类型:
整数类型:int-int、short-short、long-long;
浮点类型:float-float、double-double;
字符类型:char-char。
C语言没有byte和boolean类型。
对应的类型中,Java的long类型取值范围比C语言的更广,Java的char类型占用2个字节(16位),C语言的char类型占用1个字节(8位)。
C语言中,unsigned char可以实现Java的byte类型;而要实现Java中的boolean布尔类型,需要在代码运算后用return功能返回一个表达式,表达式0表示假,非0表示真。

实验三:Java语言基础

  1. 首先判断下列语句是否有错,然后上机检验,如果有错的请更正并说明错误原因。
    在这里插入图片描述

  2. 假设已定义变量int a=9; int b=2; 请判断以下表达式的值以及运行后a和b的值,然后上机检验。

逻辑运算符左右两边只接受boolean类型,具有短路特性
位运算符可以使用所有整数类型和boolean类型的数据,没有短路特性

  1. (a–>7) || (b++>7)
    表达式的值为true,a=8,b=2
  2. ((a–)>7) | (b++>7)
    表达式的值为true,a=7,b=3
  3. (b++>7) && ((a–)>7)
    表达式的值为false,a=7,b=3
  4. (b++>7) & ((a–)>7)
    表达式的值为false,a=7,b=3
  1. 试判断下面两段程序是否有错误。
import java.util.*;
public class sy3_4 {
	public static void main(String[] args) {
		final int i;
		i=100;
		System.out.println(i);
	}
}

//没有错误,如果final类型定义时没有初值,就还可以被赋值一次。

import java.util.*;
public class sy3_4_2 {
	public static void main(String[] args) {
		final int i;
		i=100;
		i=200;
		System.out.println(i);
	}
}

//同上,错误,不能被赋值两次。
  1. 阅读类StringExample1的代码,通过搜索引擎或猜测三个println语句输出的结果,然后运行程序验证你的结果。
import java.util.*;
public class sy3_3 {
	public static void main(String[] args) {
		String s1 = "Hello";
		String s2 = new String("Java");
		String s3 = s1 + " " + s2;
		System.out.println(s3);
		s3 = s1.toUpperCase() + " " + s2.toUpperCase();
		System.out.println(s3);
		s1 = s1.replace("Hello", "Goodbye");
		s2 = s2.replace("Java", "C");
		s3 = s1 + " " + s2;
		System.out.println(s3);
	}
}

//运行结果:
Hello Java
HELLO JAVA
Goodbye C
  1. 类ArrayAverage用于对两个数组计算平均值,main中通过调用getAver函数来计算平均值,补充两个函数中的语句使其能正常工作。
import java.util.*;
public class sy3_5 {
	public static void main(String[] args) {
		int []score1 = {61,80,60,85,82,90,100,93};
		int []score2 = new int[5];
		score2[0] = 62;
		score2[1] = 70;
		score2[2] = 82;
		score2[3] = 90;
		score2[4] = 60;
		//【1】补充语句
	}
	static double getAver(int []score) {
		double aver = 0.0;
		//【2】补充语句
		return aver;
	}
}

//【1】
double aver1 = getAver(score1);
double aver2 = getAver(score2);
System.out.println(aver1);
System.out.println(aver2);

//【2】
int i,count = 0;
double sum = 0.0;
for (i = 0;i < score.length;i++) {
	sum += score[i];
	count++;
}
aver = (double)(sum/count);

//运行结果:
81.375
72.8
//老师参考答案:
//【1】
System.out.println(getAver(score1));
System.out.println(getAver(score2));
	
//【2】
double sum = 0.0;
for(int i = 0; i < score.length; i++) {
	sum = sum + score[i];
}
aver = sum/score.length;
  1. 完成课本P57的习题15,类名定义为TestDigi,题中的“输入若干个数字”可以直接初始化一个数组,然后依次判断数组的元素,无须使用Scanner类。
import java.util.*;
public class TestDigi {
	public static void main(String[] args) {
		int []s = {2,3,9,15,22,31,64,81,91};
		int i;
		System.out.print("The Odds are:");
		for(i = 0;i < s.length;i++) 
			if(isOdd(s[i]))
				System.out.print(" " + s[i]);
		System.out.println();
		
		System.out.print("The SquareNumbers are:");
		for(i = 0;i < s.length;i++)
			if(isSquareNumber(s[i]))
				System.out.print(" " + s[i]);
		System.out.println();
		
		System.out.print("The Primes are:");
		for(i = 0;i < s.length;i++)
			if(isPrime(s[i]))
				System.out.print(" " + s[i]);
	}
	
	//判断奇数
	static boolean isOdd (int n) {
		if(n % 2 == 0)
			return false;
		
		return true;
	}
	
	//判断平方数
	static boolean isSquareNumber (int n) {
		int j;
		for(j = 1;j < n / 2;j++)
			if(n / j == j)
				return true;
		
		return false;		
	}
	
	//判断质数
	static boolean isPrime (int n) {
		int j;
		for(j = 2;j < n;j++) 
			if(n % j == 0)
				return false;
			
		return true;
	}
}

//运行结果:
The Odds are: 3 9 15 31 81 91
The SquareNumbers are: 9 64 81
The Primes are: 2 3 31
//老师参考答案
public class TestDigi2 {
	static boolean isodd(int n) { return (n%2 == 1); }
	static boolean isSquareNumber(int n) {
		int root = (int)Math.sqrt(n);
		return (root*root == n);
	}
	static boolean isPrime(int n) {
	if(n < 2)	return false;
	if(n == 2)	return true;
	for(int i = 2; i <= (int)Math.sqrt(n+1); i++) {
		if(n%i == 0)	return false;
	}
	return true;
}
	public static void main(String args) {
		int[] a = {1,2,3,8,13,17,19,298,311};
		for(int i = 0; i < a.length; i++) {
			System.out.print(a[i]+":");
			if(isodd(a[i]))
				System.out.print("奇数");
			if(isSquareNumber(a[i]))
				System.out.print("平方数");
			if(isPrime(a[i]))
				System.out.print("素数");
						System.out.println();
		}
	}
}

实验四:类与对象基础

  1. 阅读并运行课本P.66中的例子3.2,两个类都加上public限定符号,两个类放在同一个包下。
    //注意:由于加了public,两个类要分别放在自己的类文件中,文件名和类型一致。
package SY4_1;

public class ExampleUseMember {
	public static void main(String[] args) {
		Circle circle = new Circle(10);
		circle.x = 100;
		circle.y = 200;
		circle.moveTo(0,10);
		System.out.println("移动后横坐标是:" + circle.x);
		System.out.println("移动后纵坐标是:" + circle.y);
		System.out.println("圆半径长:" + circle.r);
		int m = (int)(Math.random()*10+1);
		circle.enlarge(m);
		System.out.println("放大" + m + "倍后圆半径长:" + circle.r);
		System.out.println(circle.area());
	}
}

class Circle{
	double r,x,y;
	Circle(){}
	Circle(double radius){ r = radius; }
	void moveTo(double xPos,double yPos) {
		x = xPos;y = yPos;
	}
	void enlarge(int multiple) {
		r = r*multiple;
	}
	double area() {
		return Math.PI*r*r;
	}
}
  1. 编写程序通过Math类的方法和域来实现如下功能:首先生成3个随机数,然后以这3个数为半径,分别计算其面积,最后输出这三个面积的最大值。
    //相关方法在P71
package sy4_2;

public class sy4_2 {
	public static void main(String[] args) {
		
		int i,j,count = 0;
		double max = 0;
		for(i=0;i<3;i++) {
			Circle circle = new Circle(0);
			int m = (int)(Math.random()*10+1);
			circle.radius = m;
			count++;
			System.out.println("第" + count +"个圆的半径是:" + circle.radius);
			System.out.println("第" + count +"个圆的面积是:" + circle.area());
			for(j=0;j<3;j++) {
				if(circle.area() > max)
					max = circle.area();
			}
		}
		System.out.print("最大的圆的面积是:" + max);
	}
}
		
class Circle{
	int radius;
	double area;
	Circle(int n){	}
	double area() {
		double area = Math.PI*radius*radius;
		return area;
	}
}
//老师参考答案
public class Test{
	public static void main(String args[]){
		double r1 = Math.random();
		double r2 = Math.random();
		double r3 = Math.random();
		double msize = Math.max(Math.PI*r1*r1,Math.max(Math.PI*r2*r2,Math.PI*r3*r3));
		System.out.println(msize);
	}
}
  1. 阅读并运行课本P.78中的例3.8,然后编写类SStrLoc来实现功能:给定一个字符串,通过程序判断该字符串中是否包含某个子串。如果包含,求出子串的所有出现位置。如:"abcbcbabcb34bcbd"中,"bcb"子串的出现位置为: 1,7,12。注意找到子串后,再次搜索可以直接从这个子串后开始,无须再从第二个字符开始,例如前述例子中,找到第一个bcb后,可以直接从第5个字符开始第二次搜索。
public class SStrLoc {
	public static void main(String[] args) {
		String str = "abcbcbabcb34bcbd";
		int count = 0,loc = 0,index = 0,fromIndex = 0;
		for( ; ; ) {
			index = str.indexOf("bcb",fromIndex);
			if(index < 0)
				break;
			count ++;
			loc = str.indexOf("bcb",fromIndex);
			fromIndex = index + 1;
			System.out.println("bcb第" +count + "次出现的位置是:" + loc);
		}
	}
}

//运算结果:
bcb第1次出现的位置是:1
bcb第2次出现的位置是:3
bcb第3次出现的位置是:7
bcb第4次出现的位置是:12
//老师参考答案
public class SStrLoc2{
	public static void main(String args[]){
		String str = new String("abcbcbabcb34bcbd");
		String substr = new String("bcb");
		int i = 0;
		int idx = -1;
		while((idx = str.indexOf(substr,i))!= -1){		//indexOf有很多个重载函数,可以从某个下标开始寻找
			System.out.println(idx);
			i = idx + 1;
			//步进改为每次加1,会输出1,3,7,12
			//若步进改为每次加substr.length,会输出1,7,12,取决于你想要的匹配模式
		}
	}
} 
  1. 回答问题:如何判断两个String对象是否相等?如何判断两个String对象在忽略大小写的情况下是否相等?并补充下列代码,通过代码判断几个String对象的关系。
    //P77中有判断字符串是否相等的方法,==只能判断引用(对象地址)是否相等。
    //注意S1和S2的关系、S1和S3的关系,注意阅读P74中例3.4前面的一段话。

使用equals,通过比较两个字符串字面值,可以判断两个String对象是否相等。判断两个String对象在忽略大小写的情况下是否相等,可以执行此操作:
public boolean equalsIgnoreCase(String anotherString)。

public class CompareString {
	public static void main(String[] args) {
		String s1 = "Java";
		String s2 = "Java";
		String s3 = new String("Java");
		String s4 = "java";
		if(s1.equals(s2))
			System.out.println("s1与s2代表同一个String对象");
		else
			System.out.println("s1与s2代表不同的String对象");
		if(s1.equals(s3))
			System.out.println("s1与s3代表同一个String对象");
		else
			System.out.println("s1与s3代表不同的String对象");
		if(s1.equals(s4))
			System.out.println("s1与s4代表同一个String对象");
		else
			System.out.println("s1与s4代表不同的String对象");
	}
}

//运算结果:
s1与s2代表同一个String对象
s1与s3代表同一个String对象
s1与s4代表不同的String对象
  1. 首先阅读并运行课本P80中的例3.11。假定有字符串对象s,String s=”name=zhangsan age=18 classNo=090728” ; 编写类SplitStr将上面的字符串拆分,结果如下: zhangsan 18 090728。
    //提示:首先使用空格进行拆分,再使用=进行拆分。
public class SplitStr {
	public static void main(String[] args) {
		String s1 = "name=zhangsan age=18 classNo=090728";
		String s2 = s1.replace(" ", "=");
		String[] div = s2.split("=");
		for(int i = 1;i < div.length;i+=2)
			System.out.println(div[i]);
	}
}

//运算结果:
zhangsan
18
090728
//老师参考答案
public class SplitStr {
	public static void main(String[] args) {
		String s = "name=zhangsan age=18 classNo=090728";
		String []strPair = s.split(" ");
		for(int i = 0;i < strPair.length;i++){
			String []values = strPair[i].split("=");
			System.out.println(values[1]);
		}
	}
}
  1. 编写类RevStr将输入的字符串反转并变更为大写,例如将”test” 变为 “TSET”。
    //提示:查找类String或StringBuffer,看有没有类似的方法。
    //P81,String和StringBuffer的相互转换
public class RevStr {
	public static void main(String[] args) {
		String str = "test";
		StringBuffer strBuf = new StringBuffer(str.toUpperCase());
		System.out.print(strBuf.reverse());
	}
}

//运算结果:
TSET
  1. 编写类SymStr来实现功能:给定一个字符串,判断该字符串是否对称,例如abcdcba和abcddcba都是对称的。
public class SymStr {
	public static void main(String[] args) {
		String s = "abcdcba";
		int count = (s.length()-1)/2,i;
		for(i = 0;i <= count;i++){
			if(s.charAt(i) != s.charAt(s.length()-1-i)) {
				System.out.println("该字符串不对称");
					break;
				}
			if(i == count)
			System.out.print("该字符串对称");
		}
	}
}

//运算结果:
该字符串对称
//老师参考答案
public class SymStr {
	public static void main(String[] args) {
		String str = new String("abcdcba");
		String rstr = (new StringBuffer(str)).reverse().toString();
		if(str.equals(rstr)==true){
			System.out.println(str.toString()+" is a symmetric string");
		}else {
			System.out.println(str.toString()+" is not a symmetric string");
		}
	}
}

//运算结果:
abcdcba is a symmetric string

实验五:类与对象基础

  1. 回答以下问题。
    1)如定义对象 StringBuffer ch = new StringBuffer(“Shanghai”) 则ch.length()=( 【1】 )。
    2)对于数组int t[ ][ ]={{1,2,3},{4,5,6}}来说,t.length等于( 【2】 ),t[0].length等于( 【3】 )。
    3)判断下列两个程序的输出:
    在这里插入图片描述
    在这里插入图片描述

//注意字符串使用成员方法length()来获取长度,数组使用成员变量length来获取长度。
//数组名是一个对象引用。第一个例子最后a和b指向同一个数组。

【1】 8
【2】 2
【3】 3
第一个输出:10
第二个输出:1

  1. 下图是数组myArray在内存堆上的示意图,写出可以生成这个数组的语句。
    在这里插入图片描述
 public class sy5_2 {
	public static void main(String[] args) {
		int[][] myArray = new int[3][];
		myArray[0] = new int[2];
		myArray[1] = new int[3];
		myArray[2] = new int[0];
		myArray[0][0] = 6;
		myArray[0][1] = 7;
		myArray[1][0] = 9;
		myArray[1][1] = 8;
		myArray[1][2] = 5;
	}
}
//老师参考答案
 int [][] myArray = new int[3][];
myArray[0] = new int[ ]{6,7};
myArray[1] = new int[ ]{9,8,5};
  1. 数组ca的数值如下:{{1,3,4,5},{7,8,9},{1,2},{8,7,6,5,4,3,2,1}};编写程序,使用for语句遍历整个数组的元素。
public class sy5_3 {
	public static void main(String[] args) {
		int[][] ca = {{1,3,4,5},{7,8,9},{1,2},{8,7,6,5,4,3,2,1}};
		for(int i = 0;i < ca.length;i++) {
			for(int j = 0;j < ca[i].length;j++)
				System.out.print(ca[i][j]+" ");
			
			System.out.println();
		}
	}
}

//运算结果:
1 3 4 5 
7 8 9 
1 2 
8 7 6 5 4 3 2 1 
  1. 编写程序实现下列功能:
    1)使用Random类随机填充一个长度为20的整数数组a,0<=数组元素<=100,输出所有的数组元素;
    2)查找数组a中是否包含值为60的元素;
    3)将数组a的前10个元素复制到数组b,输出b的元素;
    4)分别计算数组a和数组b的平均值。
import java.util.Arrays;
public class sy5_4 {
	public static void main(String[] args) {
		int[] a = new int[20];
		int i;
		
		//给数组a赋值并输出
		for( i = 0;i < a.length;i++) {
			a[i] = (int)(Math.random()*101);
			System.out.print(a[i]+" ");
		}
		System.out.println();
		
		//先排序再搜索数组a中是否包含60
		Arrays.sort(a);
		int m = Arrays.binarySearch(a, 60);
		if(m >= 0)
			System.out.println("查找成功,60在数组a中的位置是"+m);
		else
			System.out.println("查找失败,数组a中没有60");
		
		//将数组a的前10个元素复制到数组b,输出b
		int[] b = new int[10];
		System.arraycopy(a,0,b,0,10);
		for(i = 0;i < b.length;i++) 
			System.out.print(b[i]+" ");
		System.out.println();
		
		//分别计算数组a和数组b的平均值
		double aver1,aver2,sum1 = 0,sum2 = 0;
		for(i = 0;i < a.length;i++) 
			sum1 += a[i];
		aver1 = (double)(sum1 / a.length);
		for(i = 0;i < b.length;i++) 
			sum2 += b[i];
		aver2 = (double)(sum2 / b.length);
		System.out.println("数组a的平均数是:" + aver1);
		System.out.println("数组b的平均数是:" + aver2);
	}
}

//运算结果:
19 23 5 40 54 49 80 4 45 52 36 42 85 72 57 0 64 43 8 77 
查找失败,数组a中没有60
0 4 5 8 19 23 36 40 42 43 
数组a的平均数是:42.75
数组b的平均数是:22.0
//老师参考答案
import java.util.Arrays;
import java.util.Random;

public class EX4 {
	static double getAver(int []score) {
		double aver = 0.0;
		double sum = 0.0;
		for(int i = 0;i<score.length;i++) {
			sum = sum+score[i];
		}
		aver = sum/score.length;
		return aver;
	}

	public static void main(String[] args) {
		int []a = new int[20];
		Random r = new Random();
		for(int i = 0;i<a.length;i++) {
			a[i] = r.nextInt(101);
		}
		Arrays.sort(a);
		int idx = Arrays.binarySearch(a, 60);
		if(idx>=0)
			System.out.println("Index of 60 is "+idx);
		int []b = new int[10];
		System.arraycopy(a, 0, b, 0, 10);
		for(int i =0;i<b.length;i++)
			System.out.print(b[i]+" ");
		System.out.println();
		System.out.println("数组a的平均值为:"+getAver(a));
		System.out.println("数组b的平均值为:"+getAver(b));
	}
}

//运算结果:
9 16 17 18 18 24 29 40 42 52 
数组a的平均值为:51.85
数组b的平均值为:26.5
  1. 包装类的函数主要用于(基本数据类型/字符串/包装类)三者间的转换。通过阅读课本或搜索,通过语句举例回答如下问题(以int/Integer/String为例):

(1) 现有基本数据类型变量,如何转换为对应的包装类?如何转换为字符串?

int i = 10;
Integer i1 = new Integer(i);
String si = Integer.toString(i);

(2)现有字符串形式表示的基本数据类型,如何转换为对应的包装类?如何转换为基本数据类型?

String si = “10”;
Integer i1 = new Integer(si);
int i = Integer.parseInt(si);

(3) 现在包装类对象,如何转换为对应的基本数据?如何转换为字符串?

Integer i1 = new Integer(10);
int i = i1. intValue( );
String si = i1.toString();

实验六:类与对象基础

  1. concat是String类的成员函数,用于连接两个字符串。编写程序验证下列语句能否实现连接字符串的功能。
    string x = “abc”;
    x.concat(“def”);
    System.out.println("x = "+x);

不能,因为conta函数只能调用,而不能修改字符串本身的内容。要获取新的字符串需要创建新的字符串对象。实现字符串连接可以使用下列语句:
String y = x.concat(“def”);
System.out.println("y = " + y);

  1. append是StringBuffer类的成员函数,同样用于连接两个字符串。下列语句能否实现连接字符串的功能?编写程序验证。
    StringBuffer sb = new StringBuffer(“abc”);
    sb.append(“def”);
    System.out.println("sb = " + sb);

能,因为append函数是StringBuffer类通过重载方法得到的。

  1. 下面的代码主要用来统计通过String类连接10000个字符所花费的时间。Random类主要用来生成随机数;nanoTime()是System类的静态函数,用来返回当前时间(纳秒)。读懂下列代码并上机运行。然后使用StringBuffer类改写EX51,并对比两个程序的运行结果,哪个更快?为什么?
import java.util.Random;
public class sy6_3 {
	public static void main(String[] args) {
		Random r = new Random(System.nanoTime());
		String s = null;
		long start = System.nanoTime();//取初始纳秒值
		for(int i = 0;i < 10000;i++) {
			int digit = r.nextInt(10);//随机生成数 10>digit>=0
			s = s + digit;
			//digit连接到s后面
			//例如前三次循环分别生成了7,8,9
			//第三次循环结束后s的值为“789”
		}
		long stop = System.nanoTime();//循环结束后取结束纳秒值
		System.out.println(stop-start);
	}
}
//改写后的代码:
import java.util.Random;
public class sy6_3_2 {
	public static void main(String[] args) {
		Random r = new Random(System.nanoTime());
		StringBuffer s = new StringBuffer();
		long start = System.nanoTime();
		for(int i = 0;i < 10000;i++) {
			int digit = r.nextInt(10);
			s.append(digit);
		}
		long stop = System.nanoTime();
		System.out.println(stop-start);
		}
}

随机测试一次,使用String连接所需要的时间是58329635,使用StringBuffer连接所需要的时间是1761365。
很明显,StringBuffer运行的速度更快。因为StringBuffer对象每次申请内存时,一般都是多申请一些内存(多于实际需要的内存),以避免频繁内存申请操作;而String每增加1个字符,就向系统申请一次内存,从而导致性能下降。

  1. 阅读课本例3.30(P110)和例3.31(P112),然后完成课本习题3中的第15小题(P126)。
import java.math.BigInteger;
import java.util.Scanner;
public class sy6_4 {
	public static void main(String[] args) {
		System.out.println("请输入n的值:");
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		BigInteger sum = BigInteger.ZERO;
		for(int i = 1;i <= n;i++)
			sum = sum.add(factBig(i));
		System.out.println(sum);
	}
	
	public static BigInteger factBig(int i) {
		BigInteger result = BigInteger.ONE;
		for(int j = 1;j <= i;j++) {
			BigInteger k = BigInteger.valueOf(j);
			result = result.multiply(k);
		}
		return result;
	}
}

//运算结果:
请输入n的值:
5
153
  1. 编程实现(Calendar类/Date类):
    (1) 给定一个身份证号(可以直接在程序中定义,不需要从键盘输入),输出生日的年、月、日,并计算当天是星期几。
    (2) 计算下一个生日还有多少天(注意今年的生日可能已经过了)。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class sy6_5 {
	public static void main(String[] args) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
		SimpleDateFormat weekFormat = new SimpleDateFormat("EEE");
		String sfz = "440951201908203127";
		int y = Integer.parseInt(sfz.substring(6,10));
		int m = Integer.parseInt(sfz.substring(10,12))-1;
		int d = Integer.parseInt(sfz.substring(12,14));
		Calendar calendar = Calendar.getInstance();
		calendar.set(y, m, d);
		Date birthday = calendar.getTime();
		System.out.println("生日:" + dateFormat.format(birthday));
		System.out.println("当天是" + weekFormat.format(birthday));
		
		Calendar now = Calendar.getInstance();
		Date dateNow = now.getTime();
		System.out.println("现在的时间是" + dateFormat.format(dateNow));
		Calendar birth = Calendar.getInstance();
		birth.set(now.get(Calendar.YEAR), m, d);
		Date birthdate = birth.getTime();
		if(birthdate.after(dateNow)) {
			long count1 = (birthdate.getTime()-dateNow.getTime())/(24*60*60*1000);
			System.out.println("今年生日未过,距离生日还有" + count1 + "天");
		}
		else if(birthdate.before(dateNow)){
			long count3 = 365 - (dateNow.getTime()-birthdate.getTime())/(24*60*60*1000);
			System.out.println("今年生日已过,距离下一次生日还有" + count3 + "天");
		}
		else
			System.out.println("生日快乐!");
	}
}

//运算结果:
生日:20190820日
当天是星期二
现在的时间是20200820日
生日快乐!
//老师参考答案
import java.util.Calendar;
public class sy6_5_2 {
	static int CountDay(Calendar cl1,Calendar cl2) {
		return (int)((cl1.getTime().getTime()-cl2.getTime().getTime())/(1000*3600*24));
	}
	public static void main(String args[]) {
		String id = "440101199008191235";
		String year = id.substring(6,10);
		String month = id.substring(10, 12);
		String day = id.substring(12, 14);
		System.out.println(year+" "+month+" "+day);
		
		Calendar cl1 = Calendar.getInstance();
		Calendar cl2 = (Calendar)cl1.clone();	//两个时间完全一样,如果再次调用getInstance,秒和毫秒可能不一样
		cl1.set(cl1.get(Calendar.YEAR), Integer.parseInt(month)-1,Integer.parseInt(day));
		//比较cl1(今年的生日)和cl2(现在的时间)
		if(cl2.before(cl1)) {
			System.out.println("你的生日还有"+CountDay(cl1,cl2)+"天");
		}
		else if(cl2.after(cl1)) {
			cl1.add(Calendar.YEAR, 1);
			System.out.println("你的生日还有"+CountDay(cl1,cl2)+"天");
		}
		else {
			System.out.println("生日快乐");
		}
	}
}

//运算结果:
1990 08 19
你的生日还有364

实验七:类的设计与封装

  1. 阅读课本P138中的例4.2,并上机运行。对比例4.1,例4.2改进了什么地方?

例4.2为Rectangle类提供了一个构造器,并在这个构造器中提供了对象的初始化代码,这样既方便Rectangle对象的创建和使用,同时也避免了对象初始化代码的简单重复。因为nextId是类变量,所以nextId的值可被多个对象共享。由于构造器在每次执行创建对象时,都对nextId进行自增,这就保证在创建下一个对象时,其编号都是唯一的。

  1. 阅读课本P147中的例4.4,并上机运行。对比例4.3,例4.4改进了什么地方?

例4.4演示了如何在一个构造器中通过“this(参数)”形式调用重载的其他构造器。在这个例子中,Rectangle类的构造器2和构造器3中都通过this(参数)调用了构造器1,从而避免了对象创建功能代码的重复。

  1. 模仿课本P150中的例4.5,上机运行,然后给例4.5添加一个成员方法,这个成员方法用来判断一个矩形是否为一个正方形。
 boolean isSquare( ){
		return (getWidth( ) == getHeight( ));
	}
class Rect {
	int xTopLeft;
	int yTopLeft;
	int xBottomRight;
	int yBottomRight;
	int id;
	static int nextId;
	Rect(int xTopLeft,int yTopLeft,int xBottomRight,int yBottomRight){
		this.xTopLeft = xTopLeft;
		this.yTopLeft = yTopLeft;
		this.xBottomRight = xBottomRight;
		this.yBottomRight = yBottomRight;
		id = nextId;
		nextId++;
	}
	Rect(Rect rect) {
		this(rect.xTopLeft,rect.yTopLeft,rect.xBottomRight,rect.yBottomRight);
	}
	Rect(){		this(0,0,100,100);}
	int getWidth() {	return (xBottomRight-xTopLeft);}
	int getHeight() {	return (yBottomRight-yTopLeft);}
	int getPerimeter() {	return (getWidth()+getHeight())*2;}
	int getArea() {		return getWidth()*getHeight();}
	int compareArea(Rect rect) {
		return this.getArea()-rect.getArea();
	}
	void move(int xOffset,int yOffset) {
		xTopLeft = xTopLeft + xOffset;
		yTopLeft = yTopLeft + yOffset;
		xBottomRight = xBottomRight + xOffset;
		yBottomRight = yBottomRight + yOffset;
	}
	void move(int offset) {		move(offset,offset);}
	void moveX(int offset) {	move(offset,0);}
	void moveY(int offset) {	move(0,offset);}
	boolean isRect(int width, int height) {
		if(getWidth() == getHeight())
			return true;
		else
			return false;
	}
}

class Exam{
	public static void main(String[] args) {
		Rect rect1 = new Rect(200,100,500,400);
		Rect rect2 = new Rect();
		
		if(rect1.isRect(rect1.getWidth(), rect1.getHeight()))
			System.out.println("第一个矩形是正方形");
		else
			System.out.println("第一个矩形不是正方形");
		
		System.out.println("编号为"+rect1.id+"的矩形对象的周长与面积分别是");
		System.out.println(rect1.getPerimeter());
		System.out.println(rect1.getArea());
		System.out.println("编号为"+rect2.id+"的矩形对象的周长与面积分别是");
		System.out.println(rect2.getPerimeter());
		System.out.println(rect2.getArea());
		if(rect1.compareArea(rect2) == 0)
			System.out.println("两个矩形面积相等");
		rect1.move(10,10);
		rect1.move(10);
		rect2.moveX(10);
		rect2.moveY(10);
	}
}

//运行结果:
第一个矩形是正方形
编号为0的矩形对象的周长与面积分别是
1200
90000
编号为1的矩形对象的周长与面积分别是
400
10000
  1. 模仿课本的例4.5的矩形类,编程实现一个类似的三角形类。
class Triangle {
	int x1,x2,x3;
	int y1,y2,y3;
	int id;
	static int nextId;
	Triangle(int x1, int y1, int x2, int y2, int x3, int y3){
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
		this.x3 = x3;
		this.y3 = y3;
		id = nextId;
		nextId++;
	}
	Triangle(Triangle tri){
		this(tri.x1,tri.y1,tri.x2,tri.y2,tri.x3,tri.y3);
	}
	Triangle(){	this(10,10,5,5,15,5);}
	double getLine1() {	return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
	double getLine2() {	return Math.sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));}
	double getLine3() {	return Math.sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));}
	double getPerimeter() {	return (getLine1() + getLine2() + getLine3())*0.5;}
	double getArea() {
		return Math.sqrt(getPerimeter()*(getPerimeter()-getLine1())*(getPerimeter()-getLine2())*(getPerimeter()-getLine3()));
	}
	double compareArea(Triangle tri) {
		return this.getArea()-tri.getArea();
	}
	void move(int xOffset,int yOffset) {
		x1 = x1 + xOffset;
		y1 = y1 + yOffset;
		x2 = x2 + xOffset;
		y2 = y2 + yOffset;
		x3 = x3 + xOffset;
		y3 = y3 + yOffset;
	}
	void move(int offset) {		move(offset,offset);}
	void moveX(int offset) {	move(offset,0);}
	void moveY(int offset) {	move(0,offset);}
}

public class Test{
	public static void main(String[] args) {
		Triangle tri1 = new Triangle(50,50,10,10,30,10);
		Triangle tri2 = new Triangle(tri1);
		System.out.println("编号为"+tri1.id+"的三角形对象的周长与面积分别是");
		System.out.println(tri1.getPerimeter()*2);
		System.out.println(tri1.getArea());
		System.out.println("编号为"+tri2.id+"的三角形对象的周长与面积分别是");
		System.out.println(tri2.getPerimeter()*2);
		System.out.println(tri2.getArea());
		if(tri1.compareArea(tri2) == 0)
			System.out.println("两个三角形面积相等");
		tri1.move(10,10);
		tri1.move(10);
		tri2.moveX(10);
		tri2.moveY(10);

	}
}

//运行结果:
编号为0的三角形对象的周长与面积分别是
121.2899020449196
400.00000000000006
编号为1的三角形对象的周长与面积分别是
121.2899020449196
400.00000000000006
两个三角形面积相等
//老师参考答案
class Triangle2 {
	int x1; int y1;
	int x2; int y2;
	int x3; int y3;
	int id;
	static int nextId;
	static double getLen(int x1, int y1, int x2, int y2) {
		return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y1-y1));
	}
	Triangle2(int x1, int y1, int x2, int y2, int x3, int y3) throws Exception{
		double a = getLen(x1,y1,x2,y2);
		double b = getLen(x1,y1,x3,y3);
		double c = getLen(x2,y2,x3,y3);
		if(a==0.0 || b+c<a) throw new Exception();
		this.x1 = x1;	this.y1 = y1;	this.x2 = x2;	this.y2 = y2;
		this.x3 = x3;	this.y3 = y3;
		id = nextId;
		nextId++;
	}
	void move(int xOffset,int yOffset) throws Exception{
		this.x1 = xOffset;	this.y1 = yOffset;
		this.x2 = xOffset;	this.y2 = yOffset;
		this.x3 = xOffset;	this.y3 = yOffset;
	}
	
	double perimeter() {	//周长
		return getLen(x1,y1,x2,y2)+getLen(x1,y1,x3,y3)+getLen(x2,y2,x3,y3);
	}
	double area() {	//面积
		double aver = perimeter()/2;
		return Math.sqrt(aver*(aver-getLen(x1,y1,x2,y2))*(aver-getLen(x1,y1,x3,y3))*(aver-getLen(x2,y2,x3,y3)));
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值