写在前面
- 关于题目
涉及Java语言基础、类与对象基础、类的设计与封装、类继承与接口的设计、集合框架与泛型、异常类、嵌套类、枚举类型、输入/输出流、多线程与网络编程基础等大内容,知识点包括标识符、关键字与字面值、变量与类型、运算符与表达式、语句、类与对象、Math类、字符串:String类与StringBuffer类、数组对象、包装类、大数处理与BigInteger类、时间处理、类设计的基本思路、矩形类的初步设计、类声明与域的定义……
题目来自实验课老师布置,由于课本不在手边,所以涉及课本例题的,没有办法提供原例题。 - 关于答案
主要是我作业里自己写的代码,如果和老师发的参考答案差别较大,会发上两个答案。能力有限,如果有错误的地方,欢迎指正。 - 持续更新中……
使用教材
- Java面向对象程序设计
出版社:高等教育出版社
作者: 苏健
版次:1
重点项目: “十一五”国家规划课题研究成果
实验二:Java语言基础
- 结合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;
}
}
- 阅读课本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语言基础
-
首先判断下列语句是否有错,然后上机检验,如果有错的请更正并说明错误原因。
-
假设已定义变量int a=9; int b=2; 请判断以下表达式的值以及运行后a和b的值,然后上机检验。
逻辑运算符左右两边只接受boolean类型,具有短路特性
位运算符可以使用所有整数类型和boolean类型的数据,没有短路特性
- (a–>7) || (b++>7)
表达式的值为true,a=8,b=2- ((a–)>7) | (b++>7)
表达式的值为true,a=7,b=3- (b++>7) && ((a–)>7)
表达式的值为false,a=7,b=3- (b++>7) & ((a–)>7)
表达式的值为false,a=7,b=3
- 试判断下面两段程序是否有错误。
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);
}
}
//同上,错误,不能被赋值两次。
- 阅读类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
- 类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;
- 完成课本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();
}
}
}
实验四:类与对象基础
- 阅读并运行课本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;
}
}
- 编写程序通过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);
}
}
- 阅读并运行课本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,取决于你想要的匹配模式
}
}
}
- 回答问题:如何判断两个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对象
- 首先阅读并运行课本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]);
}
}
}
- 编写类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
- 编写类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)如定义对象 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
- 下图是数组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};
- 数组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)使用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
- 包装类的函数主要用于(基本数据类型/字符串/包装类)三者间的转换。通过阅读课本或搜索,通过语句举例回答如下问题(以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();
实验六:类与对象基础
- concat是String类的成员函数,用于连接两个字符串。编写程序验证下列语句能否实现连接字符串的功能。
string x = “abc”;
x.concat(“def”);
System.out.println("x = "+x);
不能,因为conta函数只能调用,而不能修改字符串本身的内容。要获取新的字符串需要创建新的字符串对象。实现字符串连接可以使用下列语句:
String y = x.concat(“def”);
System.out.println("y = " + y);
- append是StringBuffer类的成员函数,同样用于连接两个字符串。下列语句能否实现连接字符串的功能?编写程序验证。
StringBuffer sb = new StringBuffer(“abc”);
sb.append(“def”);
System.out.println("sb = " + sb);
能,因为append函数是StringBuffer类通过重载方法得到的。
- 下面的代码主要用来统计通过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个字符,就向系统申请一次内存,从而导致性能下降。
- 阅读课本例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
- 编程实现(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("生日快乐!");
}
}
//运算结果:
生日:2019年08月20日
当天是星期二
现在的时间是2020年08月20日
生日快乐!
//老师参考答案
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天
实验七:类的设计与封装
- 阅读课本P138中的例4.2,并上机运行。对比例4.1,例4.2改进了什么地方?
例4.2为Rectangle类提供了一个构造器,并在这个构造器中提供了对象的初始化代码,这样既方便Rectangle对象的创建和使用,同时也避免了对象初始化代码的简单重复。因为nextId是类变量,所以nextId的值可被多个对象共享。由于构造器在每次执行创建对象时,都对nextId进行自增,这就保证在创建下一个对象时,其编号都是唯一的。
- 阅读课本P147中的例4.4,并上机运行。对比例4.3,例4.4改进了什么地方?
例4.4演示了如何在一个构造器中通过“this(参数)”形式调用重载的其他构造器。在这个例子中,Rectangle类的构造器2和构造器3中都通过this(参数)调用了构造器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
- 模仿课本的例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)));
}
}