《Java黑皮书基础篇第10版》 第10章【习题】

Java语言程序设计 习题第十章

10.2章节习题

10.1 如果重新定义程序清单102中的Loan类,去掉其中的设置方法,这个类是不可改变的吗?

这个类依然是可以改变的,因为每一笔贷款作为一个对象,都是可以改变的

10.3章节习题

10.2 程序清单10-4中的BMI类是不可改变的吗?

是的

10.4章节习题

10.3 类之间的常用关系是什么?

关联、聚集和组合

10.4 什么是关联?什么是聚集?什么是组合?

关联是一种表述两个类关系的特性,聚集和组合都是特殊的关联

10.5 聚集和组合的 UML 图标识是什么?

聚集是空心棱形,组合是实心棱形

10.6 为什么聚集和组合都一起被称为组合?

在类中,聚集类和组合类都可以有被聚集类和被组合类的数据域

10.7章节习题

10.7 描述基本类型的包装类。

基本类型的包装类可以将基本类型数据作为对象使用,除了Integer和Character类代表int和char外,大部分的数值包装类都和对应的基本类型数据的名称一致

10.8 下面的每个语句可以编译成功么?

		//可以通过编译,调用了Integer类的+Integer(s: String)方法
		Integer a = new Integer("23");

		//可以通过编译,调用了Integer类的+Integer(value: int)方法
		Integer b = new Integer(23);

		//可以通过编译,调用了Integer类的+valueOf(s: String): Integer方法
		Integer c = Integer.valueOf("23");

		//可以通过编译,调用了Integer类的+parseInt(s: String, radix: int): int方法
		Integer d = Integer.parseInt("23", 8);

		//无法通过编译,Double类(所有包装类)没有无参构造方法
		Double e = new Double();

		//可以通过编译,调用了Double类的+Doub1e(s: String)
		Double f = Double.valueOf("23.45");

		//可以通过编译,调用了Integer类的+valueOf(s: String): Integer和+intValue(): int方法
		int g = (Integer.valueOf("23")).intValue();

		//可以通过编译,调用了Double类的+valueOf(s: String): Double和+DoubleValue(): double方法
		double h = (Double.valueOf("23.4")).doubleValue();

		//可以通过编译,调用了Double类的+valueOf(s: String): Double和+intValue(): int方法
		int i = (Double.valueOf("23.4")).intValue();

		可以通过编译,调用了Double类的+valueOf(s: String): Double和+toString() : String方法
		String j = (Double.valueOf("23.4")).toString();

10.9 如何将一个整数转换为一个字符串? 如何将一个数值字符串转换为一个整数? 如何将一个double值转换为字符串? 如何将一个数值型字符串转换为double值?

可以用toString方法将int/double转化为字符串

可以用parselnt方法将字符串转化为int/double

10.10 给出下面代码的输出。

public class Test {
	public static void main(String[]args) {
		Integer x = new Integer(3);
		System.out.println(x.intValue());
		System.out.println(x.compareTo(new Integer(4)));
  }
}

输出结果:

3
-1

10.11 下面代码的输出是什么?

public class Test {
	public static void mai(n String[] args) {
		System.out.println(Integer.parseInt("10"));
		System.out.println(Integer.parseInt("10", 10));
		System.outprintl(nInteg「e parseInt("10", 16));
		System.out.printl(n Integer.parseInt("11")); 				
    System.out.printl(n Integer parseInt("ll", 10));
		System.out.printl(nInteger.parseInt("ll", 16));
	}
}
10
10
16
11
11
17

10.8章节习题

10.12 什么是自动装箱和自动开箱? 下面的语句正确吗?

将基本类型值转换为包装类对象称为装箱(boxing),将包装类对象转化为基本类型值称为开箱(unboxing)。编译器会在没有相关命令的情况下,进行自动装箱和自动开箱。

		//可以通过编译,3用了自动装箱,5完成了利用Integer类的装箱
		Integer a = 3 + new Integer(5); 
		//可以通过编译,3用了自动装箱
		Integer b = 3;
		//无法通过编译,自动装箱应该输入一个double值
		Double c = 3;
		//可以通过编译,3.0用了自动装箱
		Double d = 3.0;
		//可以通过编译,3用了装箱
		int e = new Integer(3);
		//可以通过编译,3和4用了装箱
		int f = new Integer(3) + new Integer(4);

10.13 给出下面代码的输出结果。

public class Test {
	public static void main(String[]args) {
		Double x = 3.5;
		System.out.println(x.intValue());
		System.out.println(x.compareTo(4.5));
	}
}

输出结果:

3
-1

10.9章节习题

10.14 下面代码的输出是什么?

public class Test {
	public static void main(String[] args) {
		java.math.BigInteger x = new java.math.BigInteger("3");
		java.math.BigInteger y = new java.math.BigInteger("7");
		java.math.BigInteger z = x.add(y);
		System.out.println("x is " + x); 					
		System.out.println("y is " + y); 			
		System.out.println("z is " + z); 		
	} 
}

输出结果:

x is 3
y is 7
z is 10

10.10章节习题

10.15 假设 s1、s2、S3、s4 是四个字符串,给定如下语句:

String s1 = "Welcome to Java";
String s2 = s1;
String s3 = new String("Welcome to Java");
String s4 = "Welcome to Java";

下面表达式的结果是什么?

		String s1 = "Welcome to Java";
		String s2 = s1;
		String s3 = new String("Welcome to Java");
		String s4 = "Welcome to Java";
		
		//等号匹配储存地址,equals匹配内容
		//true
		System.out.println(s1==s2);
		//false
		System.out.println(s1==s3);
		//true
		System.out.println(s1==s4);
		//true
		System.out.println(s1.equals(s3));
		//true
		System.out.println(s1.equals(s4));
		//Welcome to HTML
		System.out.println("Welcome to Java".replace("Java","HTML"));
		//WelcTme tT Java
		System.out.println(s1.replace('o', 'T'));
		//WelcTme tT Java
		System.out.println(s1.replaceAll("o", "T"));
		//WelcTme to Java
		System.out.println(s1.replaceFirst("o","T"));
		//'W', 'e', 'l', 'c', 'o', 'm', 'e', ' ', 't', 'o', ' ', 'j', 'a', 'v', 'a'
		System.out.println(s1.toCharArray());
		
		//注:replace只可以替换单个字符或字符串,但是replaceAll可以使用正则表达式,更加灵活强大,例如:
		String str = "aBcd";
		//输出结果aBcd,没有变化,因为replace没法匹配正则表达式
		String newStr = str.replace("[a-z]", "*");
		System.out.println(newStr);
		//输出结果*B**,没有变化,因为replaceAll匹配了正则表达式,将所有小写字母全部换成了*
		String newStr2 = str.replaceAll("[a-z]", "*");
		System.out.println(newStr2);

10.16 为了创建一个字符串Welcome to java, 可能采用下面的语句:

String s = "Welcome to Java;

或者

String s = new String("Welcome to Java");

哪个更好? 为什么?

这道题的答案是chatGPT生成的,比标准答案写的还好。。。。。。

在这种情况下,采用第一种方式String s = "Welcome to Java";更好。

原因如下:

  1. 简洁性:直接使用字符串字面量创建字符串对象更加简洁,不需要调用构造函数。
  2. 效率:使用字符串字面量创建的字符串对象会被放入字符串常量池中,可以被JVM缓存,从而在内存使用和运行效率方面更加优化。而使用new String方式创建的字符串对象不会被放入常量池中,每次都会创建一个新的对象,从而在内存使用和运行效率方面相对较差。
  3. 可读性:使用字符串字面量创建的字符串对象更加易于理解和阅读,也更加符合Java编码习惯和规范。

总之,对于这种情况,建议优先使用字符串字面量创建字符串对象。只有在必须使用构造函数创建字符串对象的情况下,才使用new String方式。

10.17 下面代码的输出是什么?

String s1 = "Welcome to Java"; 
String s2 = s1.replace("o", "abc"); 
System.out.println(sl); 
System.out.println(s2);

输出结果:

Welcome to Java
Welcabcme tabc Java

10.18

假设s1是"Welcome"而s2是"welcome" , 为下面的陈述编写代码:

a. 用E替换s1中所有出现字符e的地方,然后将新字符串赋值给s2

b. 将"Welcome to Java and HTML"按空格分隔为一个数组tokens, 将前面两个标识赋值给s1和s2

public class Test {
	public static void main(String[] args) {
		String s1 = "Welcome";
		String s2 = "welcome";
		System.out.println(s2.replace('e', 'E'));
		
		String[] tokens = "Welcome to Java and HTML".split(" ");
		System.out.println(s1 = tokens[0]);
		System.out.println(s2 = tokens[1]);
	} 
}

输出结果:

wElcomE
Welcome
to

10.19 String类中是否有可以改变字符串内容的方法?

没有

10.20 假设字符串s是用new String()创建的,那么s.length()是多少?

0

10.21 如何将一个char值、一个字符数组或一个数值转换为一个字符串?

使用valueOf方法

10.22 为什么下面的代码会造成Nul1 PointerException异常?

public class Test {
    private String text;

    public Test(String s) {
      String text  = s;
    }

    public static void main(String[] args) {
      Test test = new Test("ABC");
      System.out.println(test.text.toLowerCase());
    }
  }

出现了NullPointerException是因为在程序运行时,尝试调用一个空对象的属性或方法。

在这个程序中,text一共出现了3次。

其中,Test类中出现了2次。在Test类中,首先声明了私有数据域text,然后声明了局部变量text,这两个text虽然是同名的,但是其实完全不同。

其次,main方法中1次,main方法中,text尝试调用toLowerCase()方法,这里的text,其实是作为空的私有数据域的text,并不是作为局部变量的text,所以在程序运行时,调用了一个空对象的方法,导致空指针异常。

10.23 下面程序的错误是什么?

  public class Test {
    String text;

    public void Test(String s) {
      text = s;
    }

    public static void main(String[] args) {
      Test test = new Test("ABC");
      System.out.println(test);
    }
  }

在Test类中,有一个普通方法Test,这里注意,这个Test方法并不是构造方法,只是一个普通的方法(构造方法不应该有void关键字)

所以,这个Test类其实有一个普通方法Test,和一个系统自动生成的无参构造方法Test(只不过重名了)

接下来运行到main方法,尝试使用参数“ABC”调用Test的构造方法,但是,Test类并没有带参数的构造方法,自然也就匹配不到对应的构造方法,所以报错,这个构造方法没有被定义

10.24 给出下面代码的输出结果。

public class Test {
  public static void main(String[] args) {
	//matches方法的参数应该是一个正则表达式,不能是一个普通字符串
	//false
    System.out.println("Hi, ABC, good".matches("ABC "));
    //true
    System.out.println("Hi, ABC, good".matches(".*ABC.*"));
    //如果replaceAll的参数是一个字符串,那么只能匹配100%精确的内容,如果参数是正则表达式,则可以根据正则表达式去匹配所有符合规则的字符串
    //A,B;C
    System.out.println("A,B;C".replaceAll(",;", "#"));
    //A#B#C
    System.out.println("A,B;C".replaceAll("[,;]", "#"));
    String[] tokens = "A,B;C".split("[,;]");
    for (int i = 0; i < tokens.length; i++)
      //A B C
      System.out.print(tokens[i] +  " ");
  }
}

10.25 给出下面代码的输出结果。

public class Test {
  public static void main(String[] args) {
    String s = "Hi, Good Morning";
    //这里m方法的功能是检测大写字母的数量
    //3
    System.out.println(m(s));
  }

  public static int m(String s) {
    int count = 0; 
    for (int i = 0; i < s.length(); i++)
      if (Character.isUpperCase(s.charAt(i)))
        count++;

    return count;
  }
}

10.11章节习题

10.26 StringBuilder和StringBuffer之间的区别是什么?

StringBuffer是同步的

10.27 如何为一个字符串创建字符串构建器? 如何从一个宇符串构建器获取字符串?

使用stringBuilder的构造方法

使用toString方法

10.28 使用StringBuilder类中的reverse方法编写三条语句,倒置字符串s

StringBuilder sb = new StringBuilder(s); 
sb.reverse();
s = sb.toString();

10.29 编写三条语句,从包含20个字符的字符串s中删除下标从4到10的子串。使用StringBuilder类中的delete方法。

StringBuilder sb = new StringBuilder(s); 
sb.delete(4, 10);
s = sb.toString();

10.30 字符串和字符串构建器内部用什么存储字符?

数组

10.31 假设给出如下所示的s1和s2,显示执行下列每条语句之后s1的结果。假定这些表达式都是相互独立的。

public class Test {
  public static void main(String[] args) {
	  StringBuilder s1 = new StringBuilder("Java");
	  StringBuilder s2 = new StringBuilder("HTML");
	  
    //Java is fun
	  s1.append(" is fun"); 
	  
    //JavaHTML
	  s1.append(s2);

    //Jais funva
	  s1.insert(2,"is fun"); 
    
    //JHTMLava
    s1.insert(1,s2);

    //要注意这个方法只是查找,并不会更改字符串
    //java
	  s1.charAt(2);

    //要注意这个方法只是求长度,并不会更改字符串
    //java
	  s1.length();

    //Jav
	  s1.deleteCharAt(3);

    //左闭右开,即实际删除1和2位置的字符,省下0和4位置的字符
    //ja
	  s1.delete(1,3);

    //avaJ
	  s1.reverse();

    //JComputera
	  s1.replace(1,3,"Computer"); 
    
    //要注意这个方法只是查找,并不会更改字符串
    //java
    s1.substring(1,3);

    //要注意这个方法只是查找,并不会更改字符串
    //java
	  s1.substring(2);
  }
}

10.32 给出下面程序的输出结果:

public class Test {  
	public static void main(String[] args) {
		String s = "Java";
		StringBuilder builder = new StringBuilder(s);
		change(s, builder);

    //Java
		System.out.println(s);
    //Java and HTML
		System.out.println(builder);
	}

		private static void change(String s, StringBuilder builder) {
      //要注意字符串不可变,下面的s只是局部变量,并不是原字符串
			s = s + " and HTML";
			builder.append(" and HTML");
		}
	}

编程练习题

*10.1 (时间类 Time)

设计一个名为 Time 的类。这个类包含:

• 表示时间的数据域hour、minute和second。

• 一个以当前时间创建Time对象的无参构造方法(数据域的值表示当前时间)

• 一个构造Time对象的构造方法,这个对象有一个特定的时间值,这个值是以毫秒表示的、从 1970年1月1日午夜开始到现在流逝的时间段(数据域的值表示这个时间)。

• 一个构造带特定的小时、分钟和秒的Time对象的构造方法。

• 三个数据域hour、minute和second各自的get方法。

• 一个名为setTime(long elapseTime)的方法使用流逝的时间给对象设置一个新时间。例如,如果流逝的时间为555550000毫秒,则转换为10小时、10分钟、10秒。

画出该类的UML图并实现这个类。编写一个测试程序,创建两个Time对象(使用newTime()和new Time(555550000),然后显示它们的小时、分钟和秒。

public class Test {  
	public static void main(String[] args) {
		Time test1 = new Time();

        Time test2 = new Time(555550000);

        Time test3 = new Time(5, 23, 55);

        System.out.println("The result for the no argument Time object is " + test1.getHour() + ":" + test1.getMin() + ":" +
                test1.getSec() + ".");

        System.out.println("The result for the single argument Time object is " + test2.getHour() + ":" + test2.getMin() + ":" +
                test2.getSec() + ".");

        System.out.println("The result for the three argument Time object is " + test3.getHour() + ":" + test3.getMin() + ":" +
                test3.getSec() + ".");
		}
	}
//_________________________UML DIAGRAM______________________________*
/*																	|
 * 							  Time  								|
 *------------------------------------------------------------------|
 * 	-hour : long													|
 * 															 		|
 *  -minute : long													|
 * 																	|
 * 	-second : long													|								
 *------------------------------------------------------------------|
 * 	 -Time(): 														|
 * 	 																|
 * 	 -Time(newTime: long):   										|
 * 																	|
 * 	 -Time(hour:long, min:long, second:long)						|
 *  																|
 * 	 getHour() : long												|
 * 																	|
 * 	 getMinute() : long												|
 * 																	|
 * 	 getSecond() : long												|
 * 	 																|
 * 	 setTime(): void												|
 *__________________________________________________________________|  */

class Time {
	private long hour;
	private long minute;
	private long second;
	
	public Time() {
        long theTime = System.currentTimeMillis();
        this.setTime(theTime);
    }

    public Time(long newTime) {
        this.setTime(newTime);
    }

    public Time(long newHour, long newMin, long newSec) {
        second = newSec;
        minute = newMin;
        hour = newHour;
    }
    
    public long getHour() {
        return hour;
    }

    public long getMin() {
        return minute;
    }

    public long getSec() {
        return second;
    }
    
    public void setTime(long elapsedTime) {
        hour = (((elapsedTime / 1000) / 60) / 60) % 24;
        second = (elapsedTime / 1000) % 60;
        minute = ((elapsedTime / 1000) / 60) % 60;
    }
}

输出结果:

The result for the no argument Time object is 9:31:44.
The result for the single argument Time object is 10:19:10.
The result for the three argument Time object is 5:23:55.
10.2 (BMI 类)

将下面的新构造方法加人到 BMI 类中:

//直接复制进去就行
public BMI(String name,int age,double weight,double feet, double inches)
10.3 (Mylnteger 类)

设计一个名为Mylnteger的类。这个类包括:

• 一个名为value的int型数据域,存储这个对象表示的int值。

• 一个为指定的int值创建MyInteger对象的构造方法。

• 一个返回int值的get方法。

• 如果值分别为偶数、奇数或素数,那么isEven()、isOdd()和isPrime()方法都会返回true

• 如果指定值分别为偶数、奇数或素数,那么相应的静态方法isEven(int)、is0dd(int)和 isPrime(int)会返回true

• 如果指定值分别为偶数、奇数或素数,那么相应的静态方法isEven(MyInteger)、 isOdd(MyInteger)和isPrime(MyInteger)会返回true

• 如果该对象的值与指定的值相等,那么equals(int)和equals(MyInteger)方法返回true

• 静态方法parseInt(char[])将数字字符构成的数组转换为一个int值

• 静态方法parseInt(String)将一个字符串转换为一个int值

画出该类的UML图并实现这个类。编写客户程序测试这个类中的所有方法。

public class Test {  
	public static void main(String[] args) {
		MyInteger test = new MyInteger(5);
		System.out.println("Try 'getValue()': " + test.getValue());
		
		System.out.println("\nTry 'isEven()': " + test.isEven());
		System.out.println("Try 'isOdd()': " + test.isOdd());
		System.out.println("Try 'isPrime()': " + test.isPrime());
		
		System.out.println("\nTry 'isEven(int a)': " + MyInteger.isEven(6));
		System.out.println("Try 'isOdd(int a)': " + MyInteger.isOdd(6));
		System.out.println("Try 'isPrime(int a)': " + MyInteger.isPrime(6));
		
		System.out.println("\nTry 'isEven(MyInteger a)': " + MyInteger.isEven(test));
		System.out.println("Try 'isOdd(MyInteger a)': " + MyInteger.isOdd(test));
		System.out.println("Try 'isPrime(MyInteger a)': " + MyInteger.isPrime(test));
		
		System.out.println("\nTry 'equals(int a)': " + test.equals(5));
		System.out.println("Try 'equals(MyInteger a)': " + test.equals(test));
		
		char[] testArray = {'1', '2', '3', '4', '5'};
		System.out.println(MyInteger.parseInt(testArray));
		System.out.println(MyInteger.parseInt("12345"));
		}
	}
//__________________________UML DIAGRAM_____________________________*
/*																	|
 * 							 MyInteger								|
 *------------------------------------------------------------------|
 *   -value: int													|
 *------------------------------------------------------------------|
 * 	 +MyInteger(newValue: int)										|
 * 	 																|
 * 	 +getValue() : int												|
 * 																	|
 * 	 +isEven(): boolean    											|
 * 	 																|
 * 	 +isOdd(): boolean												|
 *  																|
 * 	 +isPrime():boolean 											|
 * 																	|
 * 	 ___+isEven(a: int): boolean___									|
 * 																	|
 * 	 ___+isOdd(a: int): boolean___									|
 * 																	|
 * 	 ___+isPrime(a: int): boolean___								|
 * 																	|
 * 	 ___+isEven(a: MyInteger): boolean___ 							|
 * 																	|
 * 	 ___+isOdd(a: MyInteger): boolean___   					    	| 
 * 	 																|
 * 	 ___+isPrime(a: MyInteger): boolean___ 							|	
 * 																	|
 * 	 +equals(a: int): boolean										|	
 * 																	|
 * 	 +equals(a: MyInteger): boolean									|
 * 																	|
 * 	 ___+parseInt(arr: Char[]): int___								|
 * 																	|
 * 	 ___+parseInt(a: String):int___      							|			
 * _________________________________________________________________|  */


public class MyInteger {
    private int value;

    public MyInteger(int newValue) {
        this.value = newValue;
    }

    public int getValue() {
        return value;
    }

    public boolean isEven() {
        if (value % 2 == 0)
            return true;
        else
            return false;
    }

    public boolean isOdd() {
        if (value % 2 != 0)
            return true;
        else
            return false;
    }

    public boolean isPrime() {
        boolean prime = false;
        for (int i = 3; i < value / 2; i++) {
            if (value % i == 0) {
                prime = false;
            } else {
                prime = true;
                break;
            }
        }
        return prime;
    }

    public static boolean isEven(int a) {
        if (a % 2 == 0)
            return true;
        else
            return false;

    }

    public static boolean isOdd(int a) {
        if (a % 2 != 0) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean isPrime(int a) {
        boolean wellisIt = false;

        for (int i = 2; i < a / 2; i++) {
            if (a % i == 0) {
                wellisIt = false;
            } else {
                wellisIt = true;
            }

        }
        return wellisIt;
    }

    public static boolean isEven(MyInteger a) {
        return a.isEven();
    }

    public static boolean isOdd(MyInteger a) {
        return a.isOdd();
    }

    public static boolean isPrime(MyInteger a) {
        return a.isPrime();
    }

    public boolean equals(int a) {
        if (this.value == a) {
            return true;
        } else
            return false;
    }

    public boolean equals(Integer a) {
        if (this.value == a) {
            return true;
        } else {
            return false;
        }
    }

    public static int parseInt(char[] array) {
        int result = 0;
        for (int i = 0; i < array.length; i++) {
        	//考虑到ASCII码和十进制数字是不同的
            int digit = (int) array[i] - 48;
            result += digit * Math.pow(10, array.length - i - 1);
        }
        return result;
    }

    public static int parseInt(String a) {
        return Integer.parseInt(a);
    }

}

输出结果:

Try 'getValue()': 5

Try 'isEven()': false
Try 'isOdd()': true
Try 'isPrime()': false

Try 'isEven(int a)': true
Try 'isOdd(int a)': false
Try 'isPrime(int a)': false

Try 'isEven(MyInteger a)': false
Try 'isOdd(MyInteger a)': true
Try 'isPrime(MyInteger a)': false

Try 'equals(int a)': true
Try 'equals(MyInteger a)': true
12345
12345
10.4 (MyPoint类)

设计一个名为MyPoint的类,表示一个带x坐标和y坐标的点。该类包括:

• 两个带get方法的数据域x和y分别表示它们的坐标

• 一个创建点(0, 0)的无参构造方法

• 一个创建特定坐标点的构造方法

• 一个名为distance的方法,返回从该点到MyPoint类型的指定点之间的距离。

• 一个名为distance的方法,返回从该点到指定x和y坐标的指定点之间的距离。

画出该类的UML图并实现这个类。编写一个测试程序,创建两个点(0, 0)和(10, 30.5),并显示它们之间的距离。

public class Test {  
	public static void main(String[] args) {
		MyPoint p1 = new MyPoint();
		MyPoint p2 = new MyPoint(10, 30.5);
		System.out.println(p1.distance(10, 30.5));
		System.out.println(p1.distance(p2));
		}
	}
//__________________________UML DIAGRAM_____________________________*
/*																	|
 * 							  MyPoint								|
 *------------------------------------------------------------------|
 *   -x: double														|
 *   																|
 *   -y: double														|
 *------------------------------------------------------------------|
 * 	 +MyPoint()    (default: (0, 0))                                |
 *                                                                  |
 * 	 +MyPoint(x: double, y: double)                                 |
 *                                                                  |
 * 	 +getX(): double												|
 * 	 																|
 * 	 +getY(): double												|
 * 																	|
 * 	 +distance(x: double, y: double): double						|
 * 																	|
	 +distance(MyPoint: p): double									|   		
 * _________________________________________________________________|  */

class MyPoint {
	private double x;
	private double y;
	
	public MyPoint() {
		x = 0;
		y = 0;
	}
	
	public MyPoint(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
	
	public double distance(double x, double y) {
		return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2));
	}
	
	public double distance(MyPoint a) {
		return distance(a.x, a.y);
	}
}

输出结果:

32.09750769140807
32.09750769140807
10.5 (显示素教因子)

编写一个程序,提示用户输入一个正整数,然后以降序显示它的所有最小因子。

例如: 如果整数为120, 那么显示的最小因子为5、3、2、2、2。使用StackOflntegers类存储因子(例如:2、2、2、3、5), 获取之后按倒序显示这些因子。

public class Test {  
	public static void main(String[] args) {
		StackOfIntegers test = new StackOfIntegers();
		//输入一个数字去判断他的因子
		int a = 20;
		
		//判断因子
		for (int b = 1; b <= a / 2; b++) {
			if (a % b == 0)
				test.push(b);
		}
		
		//数字本身一定是因子,所以先输出出来
		System.out.print(a + " ");
		//循环打印剩下的因子
		while (test.empty() == false)
		System.out.print(test.pop() + " ");
		
	}
}
class StackOfIntegers {
    private int[] elements;
    private int size;
    public static final int DEFAULT_CAPACITY = 16;


    /**
     * Construct a stack with the default capacity 16
     */
    public StackOfIntegers() {
        this(DEFAULT_CAPACITY);
    }

    /**
     * Construct a stack with the specified maximum capacity
     */
    public StackOfIntegers(int capacity) {
        elements = new int[capacity];
    }

    /**
     * Push a new integer to the top of the stack
     */
    public void push(int value) {
        if (size >= elements.length) {
            int[] temp = new int[elements.length * 2];
            System.arraycopy(elements, 0, temp, 0, elements.length);
            elements = temp;
        }
        elements[size++] = value;
    }

    /**
     * Return and remove the top element from the stack
     */
    public int pop() {
        return elements[--size];
    }

    /**
     * Return the top element from the stack
     */
    public int peek() {
        return elements[size - 1];
    }

    /**
     * Test whether the stack is empty
     */
    public boolean empty() {
        return size == 0;
    }

    /**
     * Return the number of elements in the stack
     */
    public int getSize() {
        return size;
    }
}

输出结果:

20 10 5 4 2 1 

*10.6 (显示素教)

编写一个程序,然后按降序显示小于120的所有素数。使用StackOflntegers 类存储这些素数(例如:2、3、5、…),获取之后按倒序显示它们。

public class Test {  
	public static void main(String[] args) {
		StackOfIntegers test = new StackOfIntegers();
		
		for (int i = 2; i <= 120; i++) {
			if (isPrime(i)) {
				test.push(i);
			}
		}
		    
		 //循环打印素数
		 while (test.empty() == false)
		 System.out.print(test.pop() + " ");
		}

		public static boolean isPrime(int n) {
		    if (n <= 1) {
		        return false;
		    }
		    for (int i = 2; i <= Math.sqrt(n); i++) {
		        if (n % i == 0) {
		            return false;
		        }
		    }
		    return true;
		}	
}
class StackOfIntegers {
    private int[] elements;
    private int size;
    public static final int DEFAULT_CAPACITY = 16;


    /**
     * Construct a stack with the default capacity 16
     */
    public StackOfIntegers() {
        this(DEFAULT_CAPACITY);
    }

    /**
     * Construct a stack with the specified maximum capacity
     */
    public StackOfIntegers(int capacity) {
        elements = new int[capacity];
    }

    /**
     * Push a new integer to the top of the stack
     */
    public void push(int value) {
        if (size >= elements.length) {
            int[] temp = new int[elements.length * 2];
            System.arraycopy(elements, 0, temp, 0, elements.length);
            elements = temp;
        }
        elements[size++] = value;
    }

    /**
     * Return and remove the top element from the stack
     */
    public int pop() {
        return elements[--size];
    }

    /**
     * Return the top element from the stack
     */
    public int peek() {
        return elements[size - 1];
    }

    /**
     * Test whether the stack is empty
     */
    public boolean empty() {
        return size == 0;
    }

    /**
     * Return the number of elements in the stack
     */
    public int getSize() {
        return size;
    }
}

输出结果:

113 109 107 103 101 97 89 83 79 73 71 67 61 59 53 47 43 41 37 31 29 23 19 17 13 11 7 5 3 2 

**10.7 (游戏: ATM 机)

使用编程练习题9.7中创建的Account类来模拟一台ATM机。创建一个有 10个账户的数组,其id 为0, 1, …, 9,并初始化收支为100美元。系统提示用户输人一个id。 如果输人的id不正确,就要求用户输人正确的id。一旦接受一个id,就显示如运行示例所示的主菜单。可以选择1来査看当前的收支,选择2表示取钱,选择3表示存钱,选择4表示退出主菜单。一旦退出,系统就会提示再次输入id。所以,系统一旦启动就不会停止。

import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		Account[] atmAccounts = new Account[10];
		for (int i = 0; i < atmAccounts.length; i++) {
            atmAccounts[i] = new Account(i, 100);
        }

		while (true) {
		System.out.print("Enter an id: ");
		int id = scanner.nextInt();
		
		if (id >= 0 && id <= 9) {
		int choice = 0;
		while (choice != 4) {
			System.out.print("\nMain menu\n1: check balance\n2: withdraw\n3: deposit\n4: exit\nEnter a choice: ");
			choice = scanner.nextInt();
			
			manageAccounts(choice, id, scanner, atmAccounts);
			
		}
	}
		else 
			System.out.println("Invalid input, please input again!");
		
	}
}
	public static void manageAccounts(int newChoice, int newId, Scanner newScanner, Account[] newAtmAccounts) {
		switch (newChoice) {
			case 1: 
				System.out.println("The balance is " + newAtmAccounts[newId].getBalance());
				break;
			case 2: 
				System.out.print("Enter an amount to withdraw: ");
				double withdrawValue = newScanner.nextDouble();
				newAtmAccounts[newId].withDraw(withdrawValue);
				break;
			case 3:
				System.out.print("Enter an amount to deposit: ");
				double depositValue = newScanner.nextDouble();
				newAtmAccounts[newId].deposit(depositValue);
		}
	}
}
class Account {
	private int id;
	private double balance;
	
	Account(int id, double balance) {
		this.id = id;
		this.balance = 100;
	}
	
	int getId() {
		return id;
	}
	
	void setId(int newId) {
		this.id = newId;
	}
	
	double getBalance() {
		return balance;
	}
	
	void setbalance(int newBalance) {
		this.balance = newBalance;
	}
	
	void withDraw(double withdraw) {
		balance -= withdraw;
	}
	
	void deposit(double deposit) {
		balance += deposit;
	}
	
	@Override
    public String toString() {
        return "Account ID: " + getId() + "\nBalance: " + getBalance();
    }
  }

输出结果:

Enter an id: 1

Main menu
1: check balance
2: withdraw
3: deposit
4: exit
Enter a choice: 1
The balance is 100.0

Main menu
1: check balance
2: withdraw
3: deposit
4: exit
Enter a choice: 4
Enter an id: 
***10.8(财务: 税款类Tax)

编程练习题8.12使用数组编写一个计算税款的程序。设计一个名为Tax的类,该类包含下面的实例数据域。

• int filingStatus(四种纳税人状态之一): 0: 单身纳税人、1: 已婚共缴纳税人或合法寡妇、2: 已婚单缴纳税人、3: 家庭纳税人。使用公共静态常量 SINGLE_FILER(0)、 MARRIED_J0INTLY_0R_QUALIFYING_WIDOW(ER)(1)、MARRIED_SEPARATELY(2)和HEAD_ 0F_H0USEH0LD(3)表示这些状态。

• int[][] brackets: 存储每种纳税人的纳税等级

• double[] rates:存储每种纳税等级的税率

• double taxablelncome: 存储可征税收入

给每个数据域提供get和set方法,并提供返回税款的getTax()方法。该类还提供一个无参构造方法和构造方法Tax(filingStatus, brackets, rates, taxablelncome)

画出该类的UML图并实现这个类。编写一个测试程序,使用Tax类对所给四种纳税人打印2001年和2009年的税款表,可征税收人范围在50 000美元和60 000美元之间,间隔区间为1000美元。2009年的税率参见表3-2, 2001年的税率参见表10-1

《Java黑皮书基础篇第10版》 第10章【习题】_第1张图片

public class Test {
	private static final int SINGLE_FILER = 0;
	private static final int MARRIED_JOINTLY = 1;
	private static final int MARRIED_SEPEARTELY = 2;
	private static final int HEAD_OF_HOUSE = 3;
	public static void main(String[] args) {
		Tax tax0 = new Tax();
		
		for (int y = 2001; y < 2010; y = y + 8) {
			System.out.println("__________________________Tax tables for " + y + "__________________________");
			System.out.println("Taxable Income | Single Filer | Married Jointly | Married Seperately | Head of House");
		for (double i = 50000; i <= 60000; i = i + 1000) {
			System.out.printf("%10.0f", i);
		for (int a = 0; a < 4; a++) {
		tax0.setTaxableIncome(i);
		System.out.printf("%17.2f", tax0.getTax(y, a, i));
		}
		System.out.println();
		}
		}
	}
}
//_________________________________________UML DIAGRAM______________________________________________*
/*																									|
 * 							                   Tax													|
 *--------------------------------------------------------------------------------------------------|	
 *   -filingStatus: int																				|
 *   																								|
 *   -brackets: int[][]	                                            								|		
 *       																							|
 *   -rates: double[]																				|
 *   																								|
 *   -taxableIncome: double																			|
 *--------------------------------------------------------------------------------------------------|
 * 	 +Tax()																							|
 * 																									|
 * 	 +Tax(newStatus: int, newBrackets: int[][], newRates: double[], newTaxable: double)				|
 * 																									|
 *   +getFilingStatus(): int																		|
 *   																								|
 *   +setFilingStatus(newStatus: int): void															|
 *   																								|
 *   +getBrackets(): int[][]																		|
 *   																								|
 *   +setBrackets(newBrackets: int[][]): void														|
 *   																								|
 *   +getRates(): double[]																			|
 *   																								|
 *   +setRates(newRates: double[]): void															|
 *   																								|
 *   +getTaxableIncome(): double																	|
 *   																								|
 *   +setTaxableIncome(newTaxable: double): void													|
 *   																								|
 *   +getTax(): double																				|   						
 * _________________________________________________________________________________________________|  */

class Tax {
	private int filingStatus;
	private int[][] brackets;
	private double[] rates;
	private double taxableIncome;
	private int year;
	private static final int[][] BRACKETS_2001 = {
			{27050, 65550, 136750, 297350},   //Single filer
			{45200, 109250, 166500, 297350}, //Married jointly or qualifying widow(er)
			{22600, 54625, 83250, 148675},   //Married separately
			{36250, 93650, 151650, 297350}  //Head of household
		};
	private static final int[][] BRACKETS_2009 = {
			{8350, 33950, 82250, 171550, 372950},   //Single filer
			{16700, 67900, 137050, 208850, 372950}, //Married jointly or qualifying widow(er)
			{8350, 33950, 68525, 104425, 186475},   //Married separately
			{11950, 45500, 117450, 190200, 372950}  //Head of household
		};
	private static final double[] RATES_2001 = {0.15, 0.275, 0.305, 0.355, 0.391};
	private static final double[] RATES_2009 = {0.10, 0.15, 0.25, 0.28, 0.33, 0.35};
	
	Tax() {
		
	}
	
	Tax(int newStauts, int[][] newBrackets, double[] newRates, double newTaxable) {
		
	}
	
	public int getFilingStatus() {
		return filingStatus;
	}
	
	public void setFilingStatus(int newStatus) {
		
	}
	
	public int[][] getBrackets() {
		return brackets;
	}
	
	public void setBrackets(int[][] newBrackets) {
		
	}

	public double[] getRates() {
		return rates;
	}
	
	public void setRates(double[] newRates) {

	}
	
	public double getTaxable() {
		return taxableIncome;
	}
	
	public void setTaxableIncome(double newTaxable) {
		this.taxableIncome = newTaxable;
	}
	
	public double getTax(int year, int newFilingStatus, double newTaxableIncome) {
		double tax = 0;
		
		if (year == 2001) {
			int sepBrackets[] = BRACKETS_2001[newFilingStatus];
			if (newTaxableIncome <= sepBrackets[0])
				return newTaxableIncome * RATES_2001[0];
			int i = 1;
			tax = sepBrackets[0] * RATES_2001[0];
			
			for (i = 1; i < sepBrackets.length; i++) {
				if (newTaxableIncome <= sepBrackets[i]) {
					tax = tax + (newTaxableIncome - sepBrackets[i - 1]) * RATES_2001[i];
					break;
				}
				tax = tax + (sepBrackets[i] - sepBrackets[i - 1]) * RATES_2001[i];
			}
			
		}  
		
		else if (year == 2009) {
			int sepBrackets[] = BRACKETS_2009[newFilingStatus];
			if (newTaxableIncome <= sepBrackets[0])
				return newTaxableIncome * RATES_2009[0];
			int i = 1;
			tax = sepBrackets[0] * RATES_2009[0];
			
			for (i = 1; i < sepBrackets.length; i++) {
				if (newTaxableIncome <= sepBrackets[i]) {
					tax = tax + (newTaxableIncome - sepBrackets[i - 1]) * RATES_2009[i];
					break;
				}
				tax = tax + (sepBrackets[i] - sepBrackets[i - 1]) * RATES_2009[i];
			}
			
		}
		return tax;
	}
}
__________________________Tax tables for 2001__________________________
Taxable Income | Single Filer | Married Jointly | Married Seperately | Head of House
     50000         10368.75          8100.00         10925.00          9218.75
     51000         10643.75          8375.00         11200.00          9493.75
     52000         10918.75          8650.00         11475.00          9768.75
     53000         11193.75          8925.00         11750.00         10043.75
     54000         11468.75          9200.00         12025.00         10318.75
     55000         11743.75          9475.00         12311.25         10593.75
     56000         12018.75          9750.00         12616.25         10868.75
     57000         12293.75         10025.00         12921.25         11143.75
     58000         12568.75         10300.00         13226.25         11418.75
     59000         12843.75         10575.00         13531.25         11693.75
     60000         13118.75         10850.00         13836.25         11968.75
__________________________Tax tables for 2009__________________________
Taxable Income | Single Filer | Married Jointly | Married Seperately | Head of House
     50000          8687.50          6665.00          8687.50          7352.50
     51000          8937.50          6815.00          8937.50          7602.50
     52000          9187.50          6965.00          9187.50          7852.50
     53000          9437.50          7115.00          9437.50          8102.50
     54000          9687.50          7265.00          9687.50          8352.50
     55000          9937.50          7415.00          9937.50          8602.50
     56000         10187.50          7565.00         10187.50          8852.50
     57000         10437.50          7715.00         10437.50          9102.50
     58000         10687.50          7865.00         10687.50          9352.50
     59000         10937.50          8015.00         10937.50          9602.50
     60000         11187.50          8165.00         11187.50          9852.50

**10.9 (课程类Course)

如下改写 Course 类:

• 程序淸单10-6中数组的大小是固定的。对它进行改进,通过创建一个新的更大的数组并复制当前数组的内容来实现数组大小的自动增长

• 实现dropStudent方法

• 添加一个名为clear()的新方法,然后删掉选某门课程的所有学生

编写一个测试程序,创建一门课程,添加三个学生,删除一个学生,然后显示这门课程的学生

public class Test {
	public static void main(String[] args) {
		Course course1 = new Course("Data Structures"); 
		Course course2 = new Course("Database Systems");
		
		course1.push("Peter Jones"); 
		course1.push("Kim Smith"); 
		course1.push("Anne Kennedy");
		System.out.println("Number of students in course1: " + course1.getNumberOfStudents());
		
		course2.push("Kevin Max"); 
		course2.push("Jean Randa");
		System.out.println("Number of students in course2: " + course2.getNumberOfStudents());
		
		String[] students1 = course1.getStudents();
		System.out.print("Course 1 students: ");
		for (int i = 0; i < course1.getNumberOfStudents(); i++)
			System.out.print(students1[i] + ", ");
		
		String[] students2 = course2.getStudents();
		System.out.print("\nCourse 2 students: ");
		for (int i = 0; i < course2.getNumberOfStudents(); i++)
			System.out.print(students2[i] + ", ");
		
		course1.clear();
		course2.pop();
		System.out.print("\nNumber of students in course1: " + course1.getNumberOfStudents());
		System.out.print("\nNumber of students in course2: " + course2.getNumberOfStudents());
	}
}
public class Course {
	private String courseName;
	//相当于elements
	private String[] students = new String[100];
	//相当于size
	private int numberOfStudents;
	
	public Course(String courseName) {
		this.courseName = courseName;
	}
	
	public String[] getStudents() {
		 return students;
	}
	
	public int getNumberOfStudents() {
		return numberOfStudents;
	}
	
	public String getCourseName() {
		return courseName;
	}
	
	public void push(String value) {
		if (numberOfStudents >= students.length) {
			String[] temp = new String[students.length * 2];
			System.arraycopy(students, 0, temp, 0, students.length);
			students = temp;
		}
		students[numberOfStudents++] = value;
	}
	
	public String pop() {
		return students[--numberOfStudents];
	}
	
	public int clear() {
		for (int i = numberOfStudents; i > 0; i--)
		pop();
		return 0;
	}
	
}

输出结果:

Number of students in course1: 3
Number of students in course2: 2
Course 1 students: Peter Jones, Kim Smith, Anne Kennedy, 
Course 2 students: Kevin Max, Jean Randa, 
Number of students in course1: 0
Number of students in course2: 1
*10.10 (Queue 类)

10.6 节给出了一个用于Stack的类。设计一个名为Queue的类用于存储整数。像栈一样,队列具有元素。在栈中,元素以 “后进先出” 的方式获得。在队列中,元素以“先进先出”的方式获取。该类包含:
• 一个名为element的int[]类型的数据域,保存队列中的int值

• 一个名为 size 的数据域,保存队列中的元素个数

• 一个构造方法,使用默认的容量8来创建一个Queue对象

• 方法enqueue(int v),用于将v加人到队列中

• 方法dequeue() , 用于从队列中移除元素并返回该元素

• 方法empty(),如果队列是空的话,该方法返回 true

• 方法getSize(),返回队列的大小

画出该类的UML图并实现这个类,使之初始数组的大小为8。一旦元素个数超过了大小, 数组大小将会翻倍。如果一个元素从数组的开始部分移除,你需要将数组中的所有元素往左边改变一个位置。编写一个测试程序,增加从1到20的21个成员,然后将这些数字移除并显示他们

public class Test {
	public static void main(String[] args) {
		Queen q1 = new Queen("Queen 1");
		Queen q2 = new Queen("Queen 2");
		
		q1.push(1); 
		q1.push(2); 
		q1.push(3); 
		q1.push(4); 
		q1.push(5); 
		System.out.println("Number of integers in Queen1: " + q1.getSize());
		System.out.print("Queen 1 Integers: ");
		int[] queen1 = q1.getElements();
		for (int i = 0; i < q1.getSize(); i++)
			System.out.print(queen1[i] + ", ");
		
		q2.push(100); 
		q2.push(101); 
		q2.push(102); 
		q2.push(103); 
		System.out.println("\nNumber of integers in Queen2: " + q2.getSize());
		System.out.print("Queen2 Integers: ");
		int[] queen2 = q2.getElements();
		for (int i = 0; i < q2.getSize(); i++)
			System.out.print(queen2[i] + ", ");
		
		q1.clear();
		q2.pop();
		System.out.println("\n\nAfter clear, number of integers in Queen1: " + q1.getSize());
		System.out.println("After pop, number of integers in Queen2: " + q2.getSize());
		System.out.print("Queen2 Integers: ");
		for (int i = 0; i < q2.getSize(); i++)
			System.out.print(queen2[i] + ", ");
	}
}
public class Queen {
	private String queenName;
	//可以看到,超出数组范围后,程序仍然不会报错,因为数组被自动扩大2倍
	private int[] elements = new int[2];
	private int size;
	
	public Queen(String newQueenName) {
		this.queenName = newQueenName;
	}
	
	public int[] getElements() {
		return elements;
	}
	
	//获取数组大小(非空值)
	public int getSize() {
		int i;
		for (i = 0; i < elements.length; i++) {
			if (elements[i] == 0) 
				break;
		}
		return i;
	}
	
	public String getQueenName() {
		return queenName;
	}
	
	//加入元素,如果元素数量超过数组大小,数组大小*2
	public void push(int value) {
		if (size >= elements.length) {
			int[] temp = new int[elements.length * 2];
			System.arraycopy(elements, 0, temp, 0, elements.length);
			elements = temp;
		}
		elements[size++] = value;
	}
	
	//删除第一个被添加的元素,逻辑是创建一个新数组,新数组的第一个元素是老数组的第二个元素
	public int[] pop() {
		int[] i = new int[elements.length];
		for (int a = 1; a <= elements.length - 1; a++) {
			i[a - 1] = elements[a];
		}
		//复制数组,便于输出
		for (int k = 0; k < elements.length; k++) {
			elements[k] = i[k];
		}return elements;
	}
	
	//清空所有元素
	public int clear() {
		for (int i = size; i > 0; i--)
		pop();
		return 0;
	}
}
Number of integers in Queen1: 5
Queen 1 Integers: 1, 2, 3, 4, 5, 
Number of integers in Queen2: 4
Queen2 Integers: 100, 101, 102, 103, 

After clear, number of integers in Queen1: 0
After pop, number of integers in Queen2: 3
Queen2 Integers: 101, 102, 103, 
*10.11 (几何:Circle2D类)

定义Circle2D类,包括:

• 两个带有get方法的名为x和y的double型数据域,表明圆的中心点。

• 一个带get方法的数据域radius。

• 一个无参构造方法,该方法创建一个(x,y)值为(0,0)且radius为1的默认圆。

• 一个构造方法,创建带指定的x、y和radius的圆。

• 一个返回圆面积的方法getArea()。

• 一个返回圆周长的方法getPerimeter()。

• 如果给定的点(x,y)在圆内,那么方法contains(double x,double y)返回true,如图10-21a所示。

• 如果给定的圆在这个圆内,那么方法contains(Circle2D circle)返回true,如图10- 21b所示。

• 如果给定的圆和这个圆重叠,那么方法overlaps(Circle2D circle)返回true,如图10- 21c所示。

画出该类的 UML 图并实现这个类。编写测试程序,创建一个Circle2D对象 c1(new Circle2D(2, 2, 5.5)),显示它的面积和周长,还要显示 c1.contains(3, 3)、c1.contains(new Circle2D(4, 5,10.5))和c1.overlaps(new Circle2D(3, 5, 2.3))

public class Test {
	public static void main(String[] args) {
		Circle2D c1 = new Circle2D(2, 2, 5.5);
		System.out.printf("%.2f", c1.getArea());
		System.out.printf("\n%.2f\n", c1.getPerimeter());
		System.out.println(c1.contains(3, 3));
		System.out.println(c1.contains(new Circle2D(4, 5, 10.5)));
		System.out.println(c1.overlaps(new Circle2D(3, 5, 2.3)));	
	}
}
public class Circle2D {
	//_________________________UML DIAGRAM______________________________*
	/*																	|
	 * 							Circle2D  								|
	 *------------------------------------------------------------------|
	 * 	-x: double			(default 0)									|
	 * 															 		|
	 *  -y: double			(default 0)									|
	 * 																	|
	 * 	-radius : double	(default 1)									|
	 *------------------------------------------------------------------|
	 * 	+Circle2D()														|
	 * 	 																|
	 * 	+Circle2D(newX: double, newY: double, newRadius: double)		|
	 * 																	|
	 * 	+getX(): double													|
	 * 																	|
	 * 	+getY(): double													|
	 *  																|
	 * 	+getRadius() : double											|
	 * 																	|
	 * 	+getArea() : double												|
	 * 																	|
	 * 	+getPerimeter() : double										|
	 * 	 																|
	 *  +contains(newX: double, newY: double): boolean					|
	 *  																|
	 *  +contains(newCircle: Circle2D): boolean							|
	 *  																|
	 *  +overlaps(newCircle: Circle2D): boolean							|
	 *__________________________________________________________________|  */
	
	private double x;
	private double y;
	private double radius;
	
	public Circle2D() {
		x = 0;
		y = 0;
		radius = 1;
	}
	
	public Circle2D(double newX, double newY, double newRadius) {
		this.x = newX;
		this.y = newY;
		this.radius = newRadius;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
	
	public double getRadius() {
		return radius;
	}
	
	public double getArea() {
		return 2 * radius * Math.PI;
	}
	
	public double getPerimeter() {
		return radius * radius * Math.PI;
	}
	
	public boolean contains(double newX, double newY) {
		if (Math.pow(Math.pow(newY - y, 2) + Math.pow(newX - x, 2), 0.5) < radius)
			return true;
		else
			return false;
	}
	
	public boolean contains(Circle2D newCircle) {
		double distance = Math.sqrt(Math.pow(x - newCircle.x, 2) + Math.pow(y - newCircle.y, 2));
	    if (distance + newCircle.radius <= radius) {
	        return true;
	    } else {
	        return false;
	    }
	}
	
	public boolean overlaps(Circle2D newCircle) {
		    double distance = Math.sqrt(Math.pow(x - newCircle.x, 2) + Math.pow(y - newCircle.y, 2));
		    if (distance <= radius + newCircle.radius) {
		        return true;
		    } else {
		        return false;
		    }
	}
}

输出结果:

34.56
95.03
true
false
true
***10.12 (几何:Triangle2D类)

定义Triangle2D类,包含:

• 三个名为p1、p2和p3的MyPoint类型数据域,这三个数据域都带有get和set方法。MyPoint在编程练习题10.4中定义。

• 一个无参构造方法,该方法创建三个坐标为(0,0)、(1,1)和(2,5)的点组成的默认三角形。

• 一个创建带指定点的三角形的构造方法。

• 一个返回三角形面积的方法getArea()。

• 一个返回三角形周长的方法getPerimeter()。

• 如果给定的点p在这个三角形内,那么方法contains(MyPoint p)返回true,如图 10-22a所示。

• 如果给定的三角形在这个三角形内,那么方法contains(Triangle2D t)返回true,如图 10-22b所示。

• 如果给定的三角形和这个三角形重叠,那么方法overlaps(Triangle2D t)返回true,如图10-22c所示。

画出该类的UML图并实现这个类。编写测试程序,使用构造方法new Triangle2D(newMyPoint(2.5, 2),new MyPoint(4.2, 3),new MyPoint(5, 3.5))创建一个Triangle2D对象t1,显示它的面积和周长,并显示t1.contains(3, 3)、t1.contains(new Triangle2D(new MyPoint(2.9, 2),new MyPoint(4, 1),MyPoint(1, 3.4)))和t1.overlaps(newTriangle2D(new MyPoint(2, 5.5),new MyPoint(4, -3),MyPoint(2, 6.5)))的结果。

public class Test {  
	public static void main(String[] args) {
		Triangle2D t1 = new Triangle2D(new MyPoint(2.5, 2), new MyPoint(4.2, 3), new MyPoint(5, 3.5));
		System.out.println(t1.getArea());
		System.out.println(t1.getPerimeter());
		System.out.println(t1.contains(new MyPoint(3, 3)));
		System.out.println(t1.contains(new Triangle2D(new MyPoint(2.9, 2), new MyPoint(4, 1), new MyPoint(1, 3.4))));
		System.out.println(t1.overlaps(new Triangle2D(new MyPoint(2, 5.5), new MyPoint(4, -3), new MyPoint(2, 6.5))));
		}
	}
//__________________________UML DIAGRAM_____________________________*
/*																	|
 * 							 Triangle2D								|
 *------------------------------------------------------------------|
 *   -p1: MyPoint													|
 *   																|
 *   -p2: MyPoint													|
 *   																|
 *   -p3: MyPoint													|
 *------------------------------------------------------------------|
 * 	 +Triangle2D()                                   				|
 *                                                                  |
 * 	 +Triangle2D(p1: newMyPoint, p2: newMyPoint, p3: newMyPoint)    |
 *                                                                  |
 * 	 +getP1(): MyPoint												|
 * 	 																|
 * 	 +getP2(): MyPoint												|
 * 																	|
 * 	 +getP3(): MyPoint												|	
 * 																	|
 *   +setP1(p1: MyPoint): void										|	
 *   																|
 *   +setP2(p2: MyPoint): void										|	
 *   																|
 *   +setP3(p3: MyPoint): void										|
 * 																	|
 *   +getArea(): double												|
 *   																|
 * 	 +getPerimeter(): double										|
 * 																	|
	 +contains(p MyPoint)											|
	 																|
	 +contains(t Triangle2D)										|
	 																|
	 +overlaps(t Triangle2D)										|   		
 * _________________________________________________________________|  */

class Triangle2D {
	private MyPoint p1;
	private MyPoint p2;
	private MyPoint p3;
	
	public Triangle2D() {
		p1 = new MyPoint(0, 0);
		p2 = new MyPoint(1, 1);
		p3 = new MyPoint(2, 5);
	}
	
	public Triangle2D(MyPoint newMyPoint1, MyPoint newMyPoint2, MyPoint newMyPoint3) {
		p1 = newMyPoint1;
		p2 = newMyPoint2;
		p3 = newMyPoint3;
	}
	
	public MyPoint getP1() {
		return p1;
	}
	
	public void setP1(MyPoint p1) {
		this.p1 = p1;
	}
	
	public MyPoint getP2() {
		return p2;
	}
	
	public void setP2(MyPoint p2) {
		this.p2 = p2;
	}
	
	public MyPoint getP3() {
		return p3;
	}
	
	public void setP3(MyPoint p3) {
		this.p3 = p3;
	}
	
	 public double getArea() {
	    double side1 = p1.distance(p2);
	    double side2 = p2.distance(p3);
	    double side3 = p3.distance(p1);
	    double s = (side1 + side2 + side3) / 2;

	    return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
	}
	 
	public double getPerimeter() {
		return p1.distance(p2) + p2.distance(p3) + p1.distance(p3);
	}
	
	public boolean contains(MyPoint p) {
		double a = p2.getY() - p3.getY();
        double b = p3.getX() - p2.getX();
        double c = p3.getY() - p1.getY();
        double d = p2.getX() - p3.getX();
        double determinant = a * d - b * c;
        double maxDet = Math.max(determinant, 0);
        double minDet = Math.min(determinant, 0);
        double detOfx = p.getX() - p3.getX();
        double detOfy = p.getY() - p3.getY();
        double s = a * detOfx + b * detOfy;
        double t = c * detOfx + d * detOfy;
        double z = determinant - s - t;
        return !(s < minDet || s > maxDet) ||
                !(t < minDet || t > maxDet) ||
                !(z < minDet || z > maxDet);
	}
	
	public boolean contains(Triangle2D t) {
		return this.contains(t.getP1()) && this.contains(t.getP2()) && this.contains(t.getP3());
	}
	
	public boolean overlaps(Triangle2D t) {
		return this.contains(t.getP1()) || this.contains(t.getP2()) || this.contains(t.getP3());
	}
}
//__________________________UML DIAGRAM_____________________________*
/*																	|
 * 							  MyPoint								|
 *------------------------------------------------------------------|
 *   -x: double														|
 *   																|
 *   -y: double														|
 *------------------------------------------------------------------|
 * 	 +MyPoint()    (default: (0, 0))                                |
 *                                                                  |
 * 	 +MyPoint(x: double, y: double)                                 |
 *                                                                  |
 * 	 +getX(): double												|
 * 	 																|
 * 	 +getY(): double												|
 * 																	|
 * 	 +distance(x: double, y: double): double						|
 * 																	|
	 +distance(MyPoint: p): double									|   		
 * _________________________________________________________________|  */

class MyPoint {
	private double x;
	private double y;
	
	public MyPoint() {
		x = 0;
		y = 0;
	}
	
	public MyPoint(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
	
	public double distance(double x, double y) {
		return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2));
	}
	
	public double distance(MyPoint a) {
		return distance(a.x, a.y);
	}
}
0.02500000000000299
5.831182352959913
false
false
false
*10.13 (几何:MyRectangle2D 类)

定义MyRectangle2D类,包含:

• 两个名为x和y的double型数据域表明矩形的中心点,这两个数据域都带有get和set方法(假设这个矩形的边与x轴和y轴平行)。

• 带get和set方法的数据域width和height。

• 一个无参构造方法,该方法创建一个(x,y)值为(0,0)且width和height为1的默认矩形。

• 一个构造方法,创建带指定的x、y、width和height的矩形。

• 方法getArea()返回矩形的面积。

• 方法getPerimeter()返回矩形的周长。

• 如果给定的点(x,y)在矩形内,那么方法contains(double x,double y)返回true, 如图10-24a所示。

• 如果给定的矩形在这个矩形内,那么方法contains(MyRectangle2D r)返回true,如图 10-24b所示。

• 如果给定的矩形和这个矩形重叠,那么方法overlaps(MyRectangle2D r)返回true,如图10-24c所示。

画出该类的UML图并实现这个类。编写测试程序,创建一个MyRectangle2D对象r1(new MyRectangle2D(2, 2, 5.5, 4.9)),显示它的面积和周长,然后显示 r1.contains(3, 3)、 r1.contains(new MyRectangle2D(4, 5, 10.5, 3.2))和r1.overlaps(new MyRectangle2D(3, 5, 2.3, 5.4)) 的结果。

public class Test {  
	public static void main(String[] args) {
		Rectangle2D r1 = new Rectangle2D(2, 2, 5.5, 4.9);
		System.out.println(r1.getArea());
		System.out.println(r1.getPerimeter());
		System.out.println(r1.contains(3, 3));
		System.out.println(r1.contains(new Rectangle2D(4, 5, 10.5, 3.2)));
		System.out.println(r1.overlaps(new Rectangle2D(3, 5, 2.3, 5.4)));
		}
	}
//____________________________________UML DIAGRAM_______________________________________*
/*																						|
 * 							 Rectangle2D												|
 *--------------------------------------------------------------------------------------|
 *   -x: double																			|
 *   																					|
 *   -y: double																			|
 *   																					|
 *   -width: double																		|
 *   																					|
 *   -height: double																	|
 *--------------------------------------------------------------------------------------|
 * 	 +Rectangle2D()                                 									|
 *                                                                  					|
 * 	 +Rectangle2D(newX: double, newY: double, newWidth: double, newHeight: double)   	|
 *                                                                  					|
 * 	 +getX(): double																	|
 * 	 																					|
 * 	 +getY(): double																	|
 * 																						|
 * 	 +getWidth(): double																|
 * 																						|
 *   +getHeight(): double																|	
 * 																						|
 *   +setX(newX: double): void															|	
 *   																					|
 *   +setY(newY: double): void															|	
 *   																					|
 *   +setWidth(newWidth: double): void													|
 *   																					|
 *   +setHeight(newHeight: double): void												|
 * 																						|	
 *   +getArea(): double																	|
 *   																					|
 * 	 +getPerimeter(): double															|
 * 																						|
	 +contains(x: double, y: double): boolean											|
	 																					|
	 +contains(r Rectangle2D): boolean													|
	 																					|
	 +overlaps(r Rectangle2D): boolean													|   		
 * _____________________________________________________________________________________|  */

class Rectangle2D {
	private double x;
	private double y;
	private double width;
	private double height;
	
	public Rectangle2D() {
		this.x = 0;
		this.y = 0;
		this.width = 1;
		this.height = 1;
	}
	
	public Rectangle2D(double newX, double newY, double newWidth, double newHeight) {
		this.x = newX;
		this.y = newY;
		this.width = newWidth;
		this.height = newHeight;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
	
	public double getWidth() {
		return width;
	}
	
	public double getHeight() {
		return height;
	}
	
	public void setX(double newX) {
		this.x = newX;
	}
	
	public void setY(double newY) {
		this.y = newY;
	}
	
	public void setWidth(double newWidth) {
		this.width = newWidth;
	}
	
	public void setHeight(double newHeight) {
		this.height = newHeight;
	}
	
	public double getArea() {
		return width * height;
	}
	
	 public double getPerimeter() {
		 return (width + height) * 2;
	 }
	 
	 public boolean contains(double x, double y) {
		 MyPoint A = new MyPoint(this.x - width / 2, this.y + height / 2);  //Top left
	     MyPoint B = new MyPoint(this.x + width / 2, this.y - height / 2);  //Bottom Right
	     return x > A.getX() && y < A.getY() && x < B.getX() && y > B.getY();
	 }
	 
	 public boolean contains(Rectangle2D r) {
		  if (r.getArea() > this.getArea()) {
	            return false;
	        }
	        return ((r.getX() + r.getWidth() / 2) <= (this.getX() + this.getWidth() / 2)) &&
	                ((r.getX() - r.getWidth() / 2) >= (this.getX() - this.getWidth() / 2)) &&
	                ((r.getY() + r.getHeight() / 2) <= (this.getY() + this.getHeight() / 2)) &&
	                ((r.getY() - r.getHeight() / 2) >= (this.getY() - this.getHeight() / 2));
	 }
	 
	 public boolean overlaps(Rectangle2D r) {
		 MyPoint rec1TopLeft = new MyPoint(r.getX() - r.getWidth() / 2, r.getY() + r.getHeight() / 2);
	     MyPoint rec1BottomRight = new MyPoint(r.getX() + r.getWidth() / 2, r.getY() - r.getHeight() / 2);
	     // Points for current object rectangle
	     MyPoint rec2TopLeft = new MyPoint(this.getX() - this.getWidth() / 2, this.getY() + this.getHeight() / 2);
	     MyPoint rec2BottomRight = new MyPoint(this.getX() + r.getWidth() / 2, this.getY() - this.getHeight() / 2);

	     return (rec1TopLeft.getX() < rec2BottomRight.getX() && rec2TopLeft.getX() < rec1BottomRight.getX()) &&
	             (rec1TopLeft.getY() > rec2BottomRight.getY() && rec2TopLeft.getY() > rec1BottomRight.getY());
	 }
	 
}
//__________________________UML DIAGRAM_____________________________*
/*																	|
 * 							  MyPoint								|
 *------------------------------------------------------------------|
 *   -x: double														|
 *   																|
 *   -y: double														|
 *------------------------------------------------------------------|
 * 	 +MyPoint()    (default: (0, 0))                                |
 *                                                                  |
 * 	 +MyPoint(x: double, y: double)                                 |
 *                                                                  |
 * 	 +getX(): double												|
 * 	 																|
 * 	 +getY(): double												|
 * 																	|
 * 	 +distance(x: double, y: double): double						|
 * 																	|
	 +distance(MyPoint: p): double									|   		
 * _________________________________________________________________|  */

class MyPoint {
	private double x;
	private double y;
	
	public MyPoint() {
		x = 0;
		y = 0;
	}
	
	public MyPoint(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}
	
	public double distance(double x, double y) {
		return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2));
	}
	
	public double distance(MyPoint a) {
		return distance(a.x, a.y);
	}
}

输出结果:

26.950000000000003
20.8
true
false
true
*10.14 (MyDate 类)

设计一个名为MyDate的类,该类包含:

• 表示日期的数据域year、month和day。月份是从0开始的,即0表示一月份。

• 一个无参构造方法,该方法创建当前日期的MyDate对象。

• 一个构造方法,创建以从1970年1月1日午夜开始流逝的毫秒数为时间的MyDate对象。

• 一个构造方法,创建一个带指定年、月、日的MyDate对象。

• 三个数据域year、month和day的get方法。

• 一个名为setDate(long elapsedTime)使用流逝的时间为对象设置新数据的方法。

画出该类的UML图并实现这个类。编写测试程序,创建一个测试程序,创建两个Date对象(使用new Date()和new Date(34355555133101L),然后显示它们的小时、分钟和秒。

public class Test {
	public static void main(String[] args) {
		 MyDate myDate1 = new MyDate();
	     MyDate myDate2 = new MyDate(34355555133101L);

	     System.out.println("MyDate1:\n year=" + myDate1.getYear() + "\n month=" + myDate1.getMonth() + "\n day=" + myDate1.getDay());
	     System.out.println("MyDate2:\n year=" + myDate2.getYear() + "\n month=" + myDate2.getMonth() + "\n day=" + myDate2.getDay());
	}
}
import java.util.GregorianCalendar;

//____________________________________UML DIAGRAM_______________________________________*
/*																						|
 * 							 			MyDate											|
 *--------------------------------------------------------------------------------------|
 *   -year: int																			|
 *   																					|
 *   -month: int																		|
 *   																					|
 *   -day: int																			|   																					|																	|
 *--------------------------------------------------------------------------------------|
 * 	 +MyDate()                                 											|
 *                                                                  					|
 * 	 +MyDate(elapsedTime: long)   														|
 *                                                                  					|
 * 	 +MyDate(year: int, month: int, day: int)											|
 * 																						|
 * 	 +setDate(elapsedTime: long): void													|	
 * 	 																					|
 * 	 +getYear(): int																	|
 * 																						|
 * 	 +getMonth(): int																	|
 * 																						|
 *   +getDay(): int																		|	
 * 																						|
 * _____________________________________________________________________________________|  */

public class MyDate {
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    private int year;
    private int month;
    private int day;

    public MyDate() {
        this(System.currentTimeMillis());
    }

    public MyDate(long elapsedTime) {
        setDate(elapsedTime);
    }

    public MyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }


    public void setDate(long elapsedTime) {
        gregorianCalendar.setTimeInMillis(elapsedTime);
        this.year = gregorianCalendar.get(GregorianCalendar.YEAR);
        this.month = gregorianCalendar.get(GregorianCalendar.MONTH);
        this.day = gregorianCalendar.get(GregorianCalendar.DAY_OF_MONTH);
    }

    public int getYear() {
        return year;
    }

    public int getMonth() {
        return month;
    }

    public int getDay() {
        return day;
    }
}

输出结果:

MyDate1:
 year=2023
 month=3
 day=22
MyDate2:
 year=3058
 month=8
 day=7
*10.15 (几何:边界鉅形)

边界矩形是指包围一个二维平面上一系列点的矩形,如图10-24d所示。编写一个方法,为二维平面上一系列点返回一个边界矩形,如下所示:

public static MyRectangle2D getRectangle(double[][] points)

Rectangle2D类在编程练习题10.13 中定义。编写一个测试程序,提示用户输人5个点, 然后显示边界矩形的中心、宽度以及髙度。

public class Test {
	public static void main(String[] args) {
		double[][] points = {{1.0, 2.5}, {3, 4}, {5, 6}, {7, 8}, {9, 10}};
		BdRectangle2D test1 = new BdRectangle2D(points);
		System.out.print("The bounding rectangle's center (" + test1.getCentralX() + ", " + test1.getCentralY() + 
						"), width " + test1.getWidth() + ", height " + test1.getHeight() + ".");
	}
}
public class BdRectangle2D {
	//边界矩形的四条边一定平行于xy轴
    private double[][] points = new double[4][1];
    
    public BdRectangle2D(double[][] points) {
    	this.points = points;
    }
    public double getMaxX() {
    	double maxX = points[0][0];
    	for (int i = 0; i < 4; i++) {
    		if(points[i + 1][0] > points[i][0]) {
    			maxX = points[i + 1][0];
    		}
    	}
    	return maxX;
    }
    
    public double getMinX() {
    	double minX = points[0][0];
    	for (int i = 0; i < 4; i++) {
    		if(points[i + 1][0] < points[i][0]) {
    			minX = points[i + 1][0];
    		}
    	}
    	return minX;
    }
    
    public double getMaxY() {
    	double maxY = points[0][1];
    	for (int i = 0; i < 4; i++) {
    		if(points[i + 1][1] > points[i][1]) {
    			maxY = points[i + 1][1];
    		}
    	}
    	return maxY;
    }
    
    public double getMinY() {
    	double minY = points[0][1];
    	for (int i = 0; i < 4; i++) {
    		if(points[i + 1][1] < points[i][1]) {
    			minY = points[i + 1][1];
    		}
    	}
    	return minY;
    }
    
    public double getWidth() {
    	return Math.abs(getMaxX()) - Math.abs(getMinX());
    }
    
    public double getHeight() {
    	return Math.abs(getMaxY()) - Math.abs(getMinY());
    }
    
    public double getCentralX( ) {
    	return getMinX() + getWidth() / 2;
    }
    
    public double getCentralY() {
    	return getMinY() + getHeight() / 2;
    }
}
The bounding rectangle's center (5.0, 6.25), width 8.0, height 7.5.
*10.16 (被2或3整除)

找出能被2或3整除的前10个数字,这些数字有50个十进制位数。

import java.math.BigDecimal;

public class Test {
	public static void main (String[] args) {
		BigDecimal a = new BigDecimal("10000000000000000000000000000000000000000000000000");
		BigDecimal b = BigDecimal.valueOf(2);
		BigDecimal c = BigDecimal.valueOf(3);
		for (int i = 0; i < 10;) {
			if (a.remainder(b) == BigDecimal.ZERO || a.remainder(c) == BigDecimal.ZERO) {
				System.out.println(a);
				a = a.add(BigDecimal.ONE);
				i++;
			}
			else
				a = a.add(BigDecimal.ONE);
		}
	}
}
10000000000000000000000000000000000000000000000000
10000000000000000000000000000000000000000000000002
10000000000000000000000000000000000000000000000004
10000000000000000000000000000000000000000000000005
10000000000000000000000000000000000000000000000006
10000000000000000000000000000000000000000000000008
10000000000000000000000000000000000000000000000010
10000000000000000000000000000000000000000000000011
10000000000000000000000000000000000000000000000012
10000000000000000000000000000000000000000000000014
*10.17 (平方數)

找出大于Long.MAX_VALUE的前10个平方数。平方数是指形式为/« 的数。例如,4、 9以及16都是平方数。找到一种方使你的程序能快速运行。

import java.math.BigInteger;

public class Test {
    public static void main(String[] args) {
        BigInteger maxLongVal = BigInteger.valueOf(Long.MAX_VALUE);
        int count = 0;
        long rootNum = (long) Math.sqrt(maxLongVal.doubleValue());
        BigInteger root = BigInteger.valueOf(rootNum);
        while (count < 10) {
            root = root.add(BigInteger.ONE);
            BigInteger n2 = root.pow(2);
            if (n2.compareTo(maxLongVal) > 0) {
                System.out.println(n2);
                count++;
            }
        }
    }
}
9223372037000250000
9223372043074251001
9223372049148252004
9223372055222253009
9223372061296254016
9223372067370255025
9223372073444256036
9223372079518257049
9223372085592258064
9223372091666259081
*10.18(大素数)

编写程序找出五个大于Long.MAX_VALUE的素数。

import java.math.BigInteger;

public class Test {
    //    BigInteger TWO = BigInteger.valueOf(2L);
    static final BigInteger lowerBound = BigInteger.valueOf(Long.MAX_VALUE);
    BigInteger testNum = lowerBound;

    public static void main(String[] args) {
        Test obj = new Test();

        int idx = 0;
        while (idx < 5) {
            obj.testNum = obj.testNum.nextProbablePrime();
            System.out.println(obj.testNum);
            idx++;
        }
    }
}
9223372036854775837
9223372036854775907
9223372036854775931
9223372036854775939
9223372036854775963
* 10.19(Mersenne素数)

如果一个素数可以写成 2 p − 1 2^p -1 2p1的形式,那么该素数就称为Mersenne素数,其中的p是一个正整数。编写程序找出p≤100的所有Mersenne素数,然后显示如下所示的输出。(必须使用BigInteger来存储数字,因为它太大了,不能用1ong来存储。程序可能需要运行几个小时。)

import java.math.BigInteger;

public class Test {
    static int P = 2;
    static BigInteger TWO = BigInteger.valueOf(2L);

    public static void main(String[] args) {
        System.out.print("p     2^p - 1");

        while (P <= 100) {
            BigInteger mersennePrime = TWO.pow(P).subtract(BigInteger.ONE);
            if (mersennePrime.isProbablePrime(1)) {
                System.out.print("\n" + P + "     " + mersennePrime.toString());
                System.out.println();
                P++;
            }
        }
    }

}
p     2^p - 1
2     3

3     7

4     15

5     31
······
*10.20(近似e)

编程练习题5.26使用下面数列近似计算e:

e = 1 + 1 1 ! + 1 2 ! + 1 3 ! + 1 4 ! + ⋅ ⋅ ⋅ + 1 i ! e = 1 + \frac{1}{1!} + \frac{1}{2!} + \frac{1}{3!} + \frac{1}{4!} + ··· + \frac{1}{i!} e=1+1!1+2!1+3!1+4!1+⋅⋅⋅+i1

为了得到更好的精确度,在计算中使用25位精度的BigDecimal。编写程序显示当 i=100, 200, 1000时 e的值。

import java.math.BigDecimal;
import java.math.BigInteger;

public class Test {
	public static void main(String[] args) {
		BigDecimal e = new BigDecimal(1);
		 for (int i = 100; i <= 1000; i++) {
	            BigDecimal numerator = BigDecimal.valueOf(1.0);
	            BigDecimal denominator = new BigDecimal(factor(i));
	            BigDecimal result = numerator.divide(denominator, 25, BigDecimal.ROUND_UP);
	            e = e.add(result);
	            if (i % 100 == 0)
	                System.out.println(e);
	        }
	}
	public static BigInteger factor(int n) {
		BigInteger factorial = BigInteger.ONE;
		for (int i = 1; i <= n; i++)
		    factorial = factorial.multiply(BigInteger.valueOf(i));
		return factorial;
	}
}
1.0000000000000000000000001
1.0000000000000000000000101
1.0000000000000000000000201
1.0000000000000000000000301
1.0000000000000000000000401
1.0000000000000000000000501
1.0000000000000000000000601
1.0000000000000000000000701
1.0000000000000000000000801
1.0000000000000000000000901
10.21 (被5或6整除)

找出能被5或6整除的大于Long.MAX_VALUE的前10个数字。

import java.math.BigDecimal;

public class Test {
	public static void main(String[] args) {
		BigDecimal a = new BigDecimal(Long.MAX_VALUE);
		BigDecimal b = a.add(BigDecimal.ONE);
		
		for (int i = 0; i < 10;) {
			if (b.remainder(BigDecimal.valueOf(5)) == BigDecimal.ZERO || b.remainder(BigDecimal.valueOf(6)) == BigDecimal.ZERO) {
			    System.out.println(b);
			    b = b.add(BigDecimal.ONE);
				i++;
			}
			else
				b = b.add(BigDecimal.ONE);
		}
	}
}
9223372036854775810
9223372036854775812
9223372036854775815
9223372036854775818
9223372036854775820
9223372036854775824
9223372036854775825
9223372036854775830
9223372036854775835
9223372036854775836
**10.22 (实现String类)

Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString1):

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        MyString1 test1 = new MyString1(new char[]{'T', 'E', 'S', 'T', '1', ' ', 'S', 'U', 'C', 'C', 'E', 'S', 'S'});
        MyString1 test2 = new MyString1(new char[]{'T', 'E', 'S', 'T', '1', ' ', 'S', 'U', 'C', 'C', 'E', 'S', 'S'});
        for (int i = 0; i < test1.length(); i++) {
        	System.out.print(test1.chars[i]);
        }
        System.out.print("\n" + test1.charAt(0));
        System.out.print("\n" + test1.length());
        System.out.print("\n" + Arrays.toString(test1.substring(1, 3).chars));
        System.out.print("\n" + Arrays.toString(test1.toLowerCase().chars));
        System.out.print("\n" + test1.equals(test2));
        System.out.print("\n" + Arrays.toString(test1.valueOf(0).chars));
    }
}
public class MyString1 {
    char[] chars;

    public MyString1(char[] chars) {
        this.chars = chars;
    }

    public char charAt(int index) {
        if (chars != null && chars.length > index) {
            return chars[index];
        }
        return ' ';
    }

    public int length() {
        if (chars != null) {
            return chars.length;
        }
        return 0;
    }

    public MyString1 substring(int begin, int end) {
        char[] resChars = new char[end - begin];
        if (this.chars != null && chars.length > end) {
            for (int i = begin, resIdx = 0; i < end; i++, resIdx++) {
                resChars[resIdx] = chars[i];
            }
            return new MyString1(resChars);
        }
        return null;
    }

    public MyString1 toLowerCase() {
        if (this.chars != null) {
            char[] resChars = new char[chars.length];
            for (int i = 0; i < resChars.length; i++) {
                resChars[i] = Character.toLowerCase(chars[i]);
            }
            return new MyString1(resChars);
        }
        return null;
    }

    public boolean equals(MyString1 s) {
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] != s.chars[i]) {
                return false;
            }
        }
        return true;
    }

    public static MyString1 valueOf(int i) {
        CharSequence temp = i + "";
        return new MyString1(new char[]{temp.charAt(0)});
    }
}
TEST1 SUCCESS
T
13
[E, S]
[t, e, s, t, 1,  , s, u, c, c, e, s, s]
true
[0]
**10.23(实现String类)

在Java库中提供了String类,给出你自己对下面方法的实现(将新类命名为MyString2):

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        MyString2 test1 = new MyString2("Test Success");
        String a = "aaa";
        System.out.println(test1.compare(a));
        System.out.println(Arrays.toString(test1.substring(1).chars));
        System.out.println(Arrays.toString(test1.toUpperCase().chars));
        System.out.println(Arrays.toString(test1.toChars()));
        System.out.println(MyString2.valueOf(true));
    }
}
public final class MyString2 {
    char[] chars;

    public MyString2(String s) {
        this.chars = s.toCharArray();
    }

    public int compare(String s) {
        int currObjTotal = 0;
        int sTotal = 0;
        if (this.chars.length != s.length()) {
            int commonLength = 0;
            for (int i = 0; i < chars.length && i < s.length(); i++) {
                commonLength = i;
            }
            return this.chars[commonLength] - s.charAt(commonLength);

        }
        for (int i = 0; i < s.length(); i++) {
            currObjTotal += chars[i];
            sTotal += s.charAt(i);
        }
        return currObjTotal - sTotal;
    }

    public MyString2 substring(int begin) {
        String s = "";
        for (int i = begin; i < chars.length; i++) {
            s += chars[i];
        }
        return new MyString2(s);

    }

    public MyString2 toUpperCase() {
        char[] chs = new char[chars.length];
        for (int i = 0; i < chars.length; i++) {
            chs[i] = Character.toUpperCase(chars[i]);
        }
        return new MyString2(String.copyValueOf(chs));
    }

    public char[] toChars() {
        return chars;
    }

    public static MyString2 valueOf(boolean b) {
        return b ? new MyString2("true") : new MyString2("false");
    }

}
18
[e, s, t,  , S, u, c, c, e, s, s]
[T, E, S, T,  , S, U, C, C, E, S, S]
[T, e, s, t,  , S, u, c, c, e, s, s]
MyString2@d716361
10.24 (实现Character类)

在Java库中提供了Character类,给出你自己对这个类的实现(将新类命名为 MyCharacter)。

public class Test {
    static MyCharacter[] myCharacters = new MyCharacter[10];

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            myCharacters[i] = MyCharacter.valueOf(((int) (1 + Math.random() * 123)));
        }
        System.out.println("MyCharacter.valueOf(myCharacters[0].charValue()): " + MyCharacter.valueOf(myCharacters[0].charValue()));
        System.out.println("MyCharacter.valueOf(myCharacters[4].charValue()): " + MyCharacter.valueOf(myCharacters[4].charValue()));
        System.out.println("myCharacters[1] = " + myCharacters[1].charValue() + " , myCharacters[7] = " + myCharacters[7].charValue() + " | " +
                "myCharacters[1].compareTo" +
                "(myCharacters[7]) " +
                ":" +
                " " + myCharacters[1].compareTo(myCharacters[7]));
        System.out.println(myCharacters[5].equals(myCharacters[7]));
        System.out.println("myCharacters[6].charValue() = " + myCharacters[6].charValue() + " | MyCharacter.isDigit" +
                "(myCharacters[6].charValue()): " +
                ")" +
                ":  " + MyCharacter.isDigit(myCharacters[6].charValue()));
        System.out.println(MyCharacter.isLetter(myCharacters[5].charValue()));
        System.out.println("myCharacters[9] = " + myCharacters[9].charValue() + " | (MyCharacter.isLowerCase" +
                ", (myCharacters[9].charValue()) :" + MyCharacter.isLowerCase(myCharacters[9].charValue()));
        System.out.println("myCharacters[3] = " + myCharacters[3].charValue() + " | MyCharacter.isUpperCase" +
                "(myCharacters[3]" +
                ".charValue()" +
                ")): " + MyCharacter.isUpperCase(myCharacters[3].charValue()));
        System.out.println("myCharacters[3] = " + myCharacters[3].charValue() + ", myCharacters[4] = " + myCharacters[4].charValue()
                + " | myCharacters[3].compareTo(myCharacters[4])): " + myCharacters[3].compareTo(myCharacters[4]));
        System.out.println("myCharacters[2] = " + myCharacters[2].charValue() + " , myCharacters[8] = " + myCharacters[8].charValue() + " | myCharacters[2].compareTo(myCharacters[8])): "
                + myCharacters[2].compareTo(myCharacters[8]));

    }
}
public class MyCharacter implements java.io.Serializable, Comparable<MyCharacter> {
    public static final char MIN_VALUE = '\u0000';
    public static final char MAX_VALUE = '\uFFFF';
    private final char value;

    static final MyCharacter[] cache = new MyCharacter[128];

    static {
        for (int i = 0; i < cache.length; i++)
            MyCharacter.cache[i] = new MyCharacter((char) i);
    }


    public MyCharacter() {
        value = MIN_VALUE;
    }

    public MyCharacter(char value) {
        this.value = value;
    }

    public static MyCharacter valueOf(char c) {
        if (c <= 127) {
            return MyCharacter.cache[(int) c];
        }
        return new MyCharacter(c);
    }

    public static MyCharacter valueOf(int i) {
        return new MyCharacter((char) i);
    }

    public char charValue() {
        return value;
    }

    public static boolean isLowerCase(char ch) {
        return ((int) ch) > 96 && ((int) ch) < 123;
    }

    public static boolean isDigit(char ch) {
        return ((int) ch) >= 48 && ((int) ch) <= 57;
    }

    public static boolean isUpperCase(char ch) {
        return ((int) ch) >= 65 && ((int) ch) <= 90;
    }

    public static boolean isLetter(char ch) {
        return ((int) ch) >= 65 && ((int) ch) <= 122;
    }

    public static boolean isLetterOrDigit(char ch) {
        return isLetter(ch) || isDigit(ch);
    }

    public static char toLowerCase(char ch) {
        return Character.toLowerCase(ch);
    }

    public static char toUpperCase(char ch) {
        return Character.toUpperCase(ch);
    }

    public static int compare(char x, char y) {
        return x - y;
    }

    @Override
    public int compareTo(MyCharacter anotherMyCharacter) {
        return compare(this.value, anotherMyCharacter.value);
    }

    @Override
    public int hashCode() {
        return MyCharacter.hashCode(value);
    }


    public static int hashCode(char value) {
        return (int) value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MyCharacter) {
            return value == ((MyCharacter) obj).charValue();
        }
        return false;
    }

    @Override
    public String toString() {
        char buf[] = {value};
        return String.valueOf(buf);
    }
}
MyCharacter.valueOf(myCharacters[0].charValue()): 
MyCharacter.valueOf(myCharacters[4].charValue()): i
myCharacters[1] = x , myCharacters[7] = \ | myCharacters[1].compareTo(myCharacters[7]) : 28
false
myCharacters[6].charValue() = 1 | MyCharacter.isDigit(myCharacters[6].charValue()): ):  true
false
myCharacters[9] = - | (MyCharacter.isLowerCase, (myCharacters[9].charValue()) :false
myCharacters[3] = u | MyCharacter.isUpperCase(myCharacters[3].charValue())): false
myCharacters[3] = u, myCharacters[4] = i | myCharacters[3].compareTo(myCharacters[4])): 12
myCharacters[2] = c , myCharacters[8] = o | myCharacters[2].compareTo(myCharacters[8])): -12
**10.25 (新的字符串split方法)

String类中的split方法会返回一个字符串数组,该数组是由分隔符分隔开的子串构成的。但是,这个分隔符是不返回的。实现下面的新方法,方法返回字符串数组 ,这个数组由用匹配宇符分隔开的子串构成,子串也包括匹配字符。

public static String[] splitCString s, String regex)

例如,split(“ab#12#453”, 会 返 回ab、#、12、#和453构成的String数组

import java.util.ArrayList;
import java.util.Arrays;

public class Test {

    public static void main(String[] args) {
        /* Tests */
        String s = "ab#12#453";
        String regex = "#";
        String s2 = "a?b?gf#e";
        String regex2 = "[?#]";

        System.out.println("split(\"ab#12#453\",\"#\"): " + Arrays.toString(split(s, regex)));
        System.out.println("split(\"a?b?gf#e\",\"[?#]\"): " + Arrays.toString(split(s2, regex2)));
    }

    public static String[] split(String s, String regex) {
        ArrayList<String> splitList = new ArrayList<>();
        if (regex == null || regex.length() < 1) {
            return new String[]{"regex must not be null and length must be greater than 0"};
        }

        ArrayList<Character> splitters = new ArrayList<>();
        for (char ch : regex.toCharArray()) {
            if (ch == '[' || ch == ']') continue;
            splitters.add(ch);
        }
        String subString = "";
        for (int i = 0; i < s.length(); i++) {
            if (splitters.contains(s.charAt(i))) {
                if (subString.length() > 0) {
                    splitList.add(subString);
                    subString = "";
                }

                splitList.add(s.charAt(i) + "");
                i++;
                while (i < s.length()) {
                    if (!splitters.contains(s.charAt(i))) {
                        subString = subString.concat(s.charAt(i) + "");
                    } else {
                        splitList.add(subString);
                        subString = "";
                        splitList.add(s.charAt(i) + "");
                        break;
                    }
                    i++;
                }
            } else {
                subString = subString.concat(s.charAt(i) + "");
            }
        }
        if (subString.length() > 0) {
            splitList.add(subString);
        }
        return splitList.toArray(new String[]{});

    }
}
*10.26 (计算器)

修改程序清单7-9,接收一个字符串的表达式,其中操作符和操作数由0到多个空格隔开。例如,3+4 和 3 + 4 都是可以接受的表达式。

public class Test {
    public static void main(String[] args) {

        StringBuilder str = new StringBuilder();

        for (String arg : args) {
            str.append(arg);
        }

        String str2 = str.toString().replaceAll(" ", "");

        str2 = str2.replaceAll("[+]", "%+%");
        str2 = str2.replaceAll("[-]", "%-%");
        str2 = str2.replaceAll("[.]", "%.%");
        str2 = str2.replaceAll("[/]", "%/%");


        args = str2.split("%");

        int result = 0;

        switch (args[1].charAt(0)) {

            case '+':
                result = Integer.parseInt(args[0]) + Integer.parseInt(args[2]);
                break;

            case '-':
                result = Integer.parseInt(args[0]) - Integer.parseInt(args[2]);
                break;

            case '.':
                result = Integer.parseInt(args[0]) * Integer.parseInt(args[2]);
                break;

            case '/':
                result = Integer.parseInt(args[0]) / Integer.parseInt(args[2]);
                break;

        }
        System.out.println(args[0] + ' ' + args[1] + ' ' + args[2] + " = " + result);
    }

}
**10.27 (实现 StringBuilder类)

在Java库中提供了StringBuilder类。给出你自己对下面方法的实现(将新类命名为MyStringBuilder1):

public class Test {
    public static void main(String[] args) {
        MyStringBuilder1 stringBuilder1 = new MyStringBuilder1("SOMESTRINGTESTHERE");
        System.out.println(stringBuilder1.toLowerCase().toString());
        System.out.println(stringBuilder1.length());
        MyStringBuilder1 stringBuilder3 = stringBuilder1.append(12);
        System.out.println(stringBuilder1.toString());
        System.out.println(stringBuilder3.toString());
        MyStringBuilder1 stringBuilder2 = new MyStringBuilder1("AddedSomeStringhere");
        stringBuilder1.append(stringBuilder2);
        System.out.println(stringBuilder1.toString());
        System.out.println(stringBuilder1.substring(3,11));

    }
}
public class MyStringBuilder1 {
    char[] values;

    public MyStringBuilder1(String s) {
        values = s.toCharArray();
    }

    public MyStringBuilder1 append(MyStringBuilder1 s) {
        int oldLength = this.values.length;
        char[] nuValues = new char[oldLength + s.length()];
        System.arraycopy(this.values, 0, nuValues, 0, oldLength);
        System.arraycopy(s.values, 0, nuValues, oldLength, s.length());
        this.values = nuValues;
        return this;
    }

    public MyStringBuilder1 append(int i) {
        int oldLength = values.length;
        String temp = i + "";
        char[] nuVals = new char[values.length + temp.length()];
        char[] integer = temp.toCharArray();
        System.arraycopy(this.values, 0, nuVals, 0, this.values.length);
        System.arraycopy(integer, 0, nuVals, oldLength, integer.length);
        this.values = nuVals;
        return this;

    }

    public int length() {
        return values.length;
    }

    public char charAt(int index) {
        return values[index];
    }

    public MyStringBuilder1 toLowerCase() {
        char[] nu = new char[this.values.length];
        for (int i = 0; i < nu.length; i++) {
            nu[i] = Character.toLowerCase(this.values[i]);
        }
        return new MyStringBuilder1(String.valueOf(nu));
    }

    public MyStringBuilder1 substring(int begin, int end) {
        char[] nuVals = new char[end - begin];
        System.arraycopy(this.values, begin, nuVals, 0, nuVals.length);
        this.values = nuVals;
        return this;
    }

    @Override
    public String toString() {
        return String.valueOf(values);
    }
}
somestringtesthere
18
SOMESTRINGTESTHERE12
SOMESTRINGTESTHERE12
SOMESTRINGTESTHERE12AddedSomeStringhere
ESTRINGT
**10.28 (实现 StringBuilder类)

在Java库中提供了StringBuilder类。给出你自己对下面方法的实现(将新类命名为MyStringBuilder2):

public class Test {
    public static void main(String[] args) {
        //Test StringBuilder2
        MyStringBuilder2 myStringBuilder2 = new MyStringBuilder2("SuperCalifradolistic");
        System.out.print("Start MyStringBuilder2 values: ");
        System.out.println(myStringBuilder2.toString());
        System.out.print("ToUpperCase: ");
        System.out.println(myStringBuilder2.toUpperCase().toString());
        System.out.print("Insert: ");
        myStringBuilder2.insert(3, new MyStringBuilder2("TESTinsertTEST"));
        System.out.println(myStringBuilder2.toString());
        System.out.print("Reverse: ");
        System.out.println(myStringBuilder2.reverse().toString());
        System.out.println("subString: " + myStringBuilder2.substring(5).toString());
    }

}

import java.util.Arrays;

public final class MyStringBuilder2 {

    char[] values;

    public MyStringBuilder2() {
        this("".toCharArray());
    }

    public MyStringBuilder2(char[] chars) {
        this.values = chars;
    }

    public MyStringBuilder2(String s) {
        this(s.toCharArray());
    }


    public MyStringBuilder2 insert(int offset, MyStringBuilder2 s) {
        char[] nuVals = new char[s.values.length + offset];
        System.arraycopy(this.values, 0, nuVals, 0, offset);
        System.arraycopy(s.values, 0, nuVals, offset, s.values.length);
        this.values = nuVals;

        return this;
    }


    public MyStringBuilder2 reverse() {
        char[] nuVals = new char[values.length];
        for (int i = values.length - 1, j = 0; i >= 0; i--, j++) {
            nuVals[j] = values[i];
        }
        this.values = nuVals;
        return this;

    }

    public MyStringBuilder2 substring(int begin) {
        String s = "";
        for (int i = begin; i < values.length; i++) {
            s += values[i];
        }
        return new MyStringBuilder2(s);

    }

    public MyStringBuilder2 toUpperCase() {
        String s = String.valueOf(values);
        String UC = s.toUpperCase();
        values = Arrays.copyOf(UC.toCharArray(), values.length);
        return this;
    }

    @Override
    public String toString() {
        return String.valueOf(values);
    }
}

Start MyStringBuilder2 values: SuperCalifradolistic
ToUpperCase: SUPERCALIFRADOLISTIC
Insert: SUPTESTinsertTEST
Reverse: TSETtresniTSETPUS
subString: resniTSETPUS

你可能感兴趣的:(java,开发语言)