Java Review (二十、基础类库----常用类:Object、String、StringBuffer、StringBuilder、Math)
@
Object 类
Object 类是所有类、数组、枚举类的父类 ,也就是说, Java 允许把任何类型的对象赋给 Object 类型的变量 。 当定义一个类时没有使用 extends 关键字为它显式指定父类,则该类默认继承 Object 父类。
因为所有的 Java 类都是 Object 类的子类 , 所以任何 Java 对象都可以调用 Object 类的方法 。 Object类提供了如下几个常用方法 :
- boolean equals(Object obj): 判断指定对象与该对象是否相等 。 此处相等的标准是 , 两个对象是同一个对象,因此该 equalsO方法通常没有太大的实用价值 。
- protected void fmalize(): 当系统中没有引用变量引用到该对象时,垃圾回收器调用 此方法来清理该对象的资源 。
- Class<?> getClass(): 返回该对象的运行时类。
- int hashCode(): 返回该对象的 hashCode 值。在默认情况下, Object 类的 hashCode()方法根据该对象的地址来计算 但很多类都 重写了 Object 类的 hashCode()方法,不再根据地址来计算其 hashCode()方法值 。
- String toString(): 返回 该对象 的 字符串表示 , 当程序用System.out.println()方法输出一个对象,或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString()方法返回该对象的字符串表示 。 Object 类的 toString()方法返回"运行时类名@十六进制 hashCode 值"格式的字符串 ,但很多类都重写了 Object 类 的 toString()方法,用于返回可以表述该对象信息的字符串。
除此之外 , Object 类还提供了 wai() 、 notify() 、 notifyAll()几个方法,通过这几个方法可以控制线程的暂停和运行。
Java 还提供了一个 protected 修饰的 clone()方法 , 该方法用于帮助其他对 象来实现"自我克隆",所谓"自我克隆"就是得到一个当前对象的副本,而且二者之间完全隔离。由于 Object 类提供的 clone()方法使用了 protected 修饰,因此该方法只能被子类重写或调用。
class Address {
String detail;
public Address(String detai1) {
this.detail = detai1;
}
}
// 实现 C1oneab1e 接口
class User implements Cloneable {
int age;
Address address;
public User(int age) {
this.age = age;
address = new Address("广州天河 ");
}
// 通过调用 super.c1one ()来实现 c1one ()方法
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
User u1 = new User(29);
// clone 得到 u1对象的副本
User u2 = u1.clone();
// 判断 u1 、 u2 是否相同
System.out.println(u1 == u2); // ①
// 判断 u1 、 u2 的 address 是否相同
System.out.println(u1.address == u2.address); // ②
}
}
Object 类提供的 Clone机制只对对象里各实例变量进行"简单复制",如果实例变量的类型是引用类型, Object 的 Clone 机制也只是简单地复制这个引用变量,这样原有对象的引用类型的实例变量与克隆对象的引用类型的实例变量依然指向内存中的同一个实例,所以上面程序在②号代码处输出 true。上面程序"克隆 "出来的u1、u2 所指向的对 象在内存中的存储示意图如图所示 。
API:java.lang.Object
String 、 StringBuffer 和 StringBuilder 类
字符串就是一连串的字符序 列, Java 提供 了 String 、 StringBuffer 和 StringBuilder 三个类来封装宇符串,并提供了 一系列方法来操作字符串对象 。
- String 类是不可变类 ,即 一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的 , 直至这个对象被销毁。
- StringBuffer 对 象 则代 表一个字符序列可变的 字符串 ,当 一个 StringBuffer 被创建以后,通过StringBuffer 提供的 append() 、 insert() 、 reverse() 、 setCharAt() 、 setLength()等方法可以改变这个字符串对象的宇符序列。一旦通过 StringBuffer 生成了 最终想要的字符串,就可以调用它的 toStringO方法将其转换为一个 String 对象 。
- StringBuilder 类是 JDK 1.5 新增的类 ,它也代表可变宇符串对象 。 实际上, StringBuilder 和 StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是 , StringBuffer 是线程安全的,而 StringBuilder则没有实现线程安全功能 ,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象, 则应该优先考虑使用 StringBuilder 类。
String类
String类提供了大量构造器来创建String对象,其中如下几个有特殊用途:
- String():创建一个包含0个字符串序列的String对象(并不是返回null)。
- String(byte[] bytes, Charset charset):使用指定的字符集将指定的byte[擞组解码成一个新的String 对象。
- String(byte[] bytes, int offset, int length):使用平台的默认字符集将指定byte[]数组从ofifeet开始、长度为length的子数组解码成一个新的String对象。
- String(byte[] bytes, int offset, int length, String charsetName):使用指定的字符集将指定的 byte[]数 组从offset开始、长度为length的子数组解码成一个新的String对象。
- String(byte[] bytes, String charsetName):使用指定的字符集将指定的byte[]数组解码成一个新的 String 对象。
- String(char[] value, int offset, int count):将指定的字符数组从offset开始、长度为count的字符元 素连缀成字符串。
- String(String original):根据字符串直接量来创建一个String对象。也就是说,新创建的String 对象是该参数字符串的副本。
- String(StringBuffer buffer):根据 StringBuffer 对象来创建对应的 String 对象。
- String(StringBuilder builder):根据 StringBuilder 对象来创建对应的 String 对象。
String 类也提供了大量方法来操作字符串对象:
- char charAt(int index): 获取字符串中指定位置的字符。其中 , 参数 index 指 的是字符串的序数,字符串的序数从 0 开始到 length()-l 。 如下代码所示:
String s = new String("fkit.org");
System .out. println("s.charAt(5): "+ s.charAt(5) );
结果为:
s . charAt(5) : 0
- int compareTo(String anotherString): 比较两个宇符串的大小 。 如果两个字符串的字符序列相等,则返回 0; 不相等时,从两个字符串第 0 个字符开始比较,返回第一个不相等的字符差。另一种情况,较长字符串的前面部分恰巧是较短的字符串,则返回它们的长度差。
String s1 = new String( "abcdefghijklmn");
String s2 = new String( "abcdefghij ");
String s3 = new String( "abcdefghijalmn") ;
System.out .println( "sl. compareTo(s2) : " + sl. compareTo(s2) ) ; //返回长度差
System.out.println( "sl. compareTo (s3): " + sl. compareTo(s3) ) ; //返回 'k'-'a' 的差
结果为 :
s1.compareTo(s2): 4
s1.compareTo(s3) : 10
- String concat(String s):将该 String 对象与调用对象连接在一起。与 Java 提供的字符串连接运算符" +"的功能相同。
- boolean contentEquals(StringBuffer sb): 将该 String 对象与 StringBuffer 对象 sb 进行比较,当它们包含的字符序列相同时返回 true 。
- static String copyValueOf(char[] data): 将字符数组连缀成字符串,与 String(char[] content)构造器的功能相同 。
- static String copyValueOf(char[] data, int offset, int count): 将 char 数组的子数组中的元素连缀成字符串,与 String(char[] value, int offset, int count)构造器的功能相同 。
- boolean endsWith(String suffix): 返回该 String 对象是否以 suffix 结尾 。
String s1 = "fkit. org"; String s2 = ". org";
System.out .println("s1 .endsWith(s2): " + s1.endsWith(s2) );
结果为:
s1 .endsWith(s2): true
- boolean equals(Object anObject): 将该字符串与指定对象比较,如果二者包含的字符序列相等,则返回 true; 否则返回 false 。
- boolean equalsIgnoreCase(String s):与前 一个方法基本相似,只是忽略字符的大小写 。
- byte[] getBytes(): 将 该 String 对象转换成 byte 数组 。
- void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): 该方法将字符串中从 srcBegin 开始,到 srcEnd 结束的字符复制到 dst 字符数组中,其中 dstBegin 为目标字符数组的起始复制位置。
char[] s1 = {'I' ,' ', ' l' , ' o' , ' v' , ' e ' ,' ', 'j' , ' a' , ' v ' , ' a'); // s1=1 love_java
String s2 = new String( "ejb");
s2 .getChars(0 , 3, s1 , 7); // s1=I love java
System.out . println ( s1 );
结果为:
I love java
- int indexOf(int ch): 找出 ch 字符在该字符串中第一次 出现的位置 。
- int indexOf(int ch, int fromIndex): 找出 ch 字符在该字符串中从企fromIndex 开始后第一 次出现的位置。
- int indexOf(String s):找出 str 子字符串在该宇符串中第 一次出现的位置 。
- int indexOf(String s, int fromIndex): 找出 s位子字符串在该字符串中从 fromIndex 开始后第一次出现的位置。
String s = "www.fkit .org"; String ss = "it ";
System. out .print1n( "s.indexOf( ' r ' ): " + s .indexOf( ' r ') );
System .out.print1n( "s . indexOf( ' r ' , 2) : " + s.indexOf('r ' , 2) );
System.out.print1n( " s . indexOf(ss): " + s.indexOf(ss)) ;
结果为:
s .indexOf( 'r'): 10
s . indexOf (' r ' , 2) : 10
s . indexOf (ss) : 6
- int lastIndexOf(int ch): 找出 ch 字符在该字符串中最后一次出现的位置。
- int lastIndexOf(int ch, int fromIndex): 找出 ch 字符在该字符串 中从 fromIndex 开始后最后一次出现的位置 。
- int lastIndexOf(String str):找出 str子字符串在该字符串中最后 一次 出现的位置 。
- int lastIndexOf(String str, int fromIndex): 找出 str 子字符串在该字符串中从 台fromlndex 开始后最后一次出现的位置 。
- int length(): 返回当前字符串长度。
- String replace(char oldChar, char newChar): 将字符串中的第一个 oldChar 替换成 newChar 。
- boolean startsWith(String prefix): 该 String 对象是否以 prefix 开始。
- boolean startsWith(String prefix , int toffset): 该 String 对象从 toffset 位置算起,是否以 prefix 开始。
String s = "www . fki t .org"; String ss = "www"; String sss = "fkit ";
System.out .print1n("s.startsWith (ss): " + s.startsWith(ss) );
System.out .print1n( "s.startsWith(sss , 4): " + s.startsWith (sss , 4));
结果为 :
s .startsWith(ss) : true
s.startsWith(sss , 4): true
- String substring(int beginlndex): 获取从 beginlndex 位置开始到结束的子字符串。
- String substring(int beginlndex, int endIndex): 获取从 beginIndex 位置开始到 endlndex 位置的子字符串。
- char[] toCharArray(): 将该 String 对象转换成 char 数组。
- String toLowerCase(): 将字符串转换成小写。
- String toUpperCase(): 将字符串转换成大写。
String s = "fkjava.org ";
System.out.print1n( "s.toUpperCase() : " + s . toUpperCase()) ;
System.out.print1n( "s.toLowerCase(): " + s.toLowerCase()) ;
结果为 :
s . toUpperCase() : FKJAVA .ORG
s.toLowerCase() : fkjava .org
- static String valueOf(X x): 一系列用于将基本类型值转换为 String 对象的方法 。
String 类是不可变的, String类的实例一旦生成就不会再改变了。
例如如下代码:
String str1 = "java";
str1 = str1 + "struts ";
str1 = str1 + " spring";
上面程序除使用了 3 个字符串直接量之外,还会额外生成 2 个字符串直接量一一 "java"和 "struts"连接生成的 "javastruts" , 接着 "javastruts"与 "spring"连接生成 的 "javastrutsspring" , 程序中 的 strl 依次指向 3个不同的字符串对象。
字符串存储
对于不同版本的JDK,String类在内存中有不同的优化方式。具体来说,早期JDK版本的String总是以char[]存储,它的定义如下:
public final class String {
private final char[] value;
private final int offset;
private final int count;
}
而较新的JDK版本的String则以byte[]存储:如果String仅包含ASCII字符,则每个byte存储一个字符,否则,每两个byte存储一个字符,这样做的目的是为了节省内存,因为大量的长度较短的String通常仅包含ASCII字符:
public final class String {
private final byte[] value;
private final byte coder; // 0 = LATIN1, 1 = UTF16
}
API:java.lang.String
StringBuilder、StringBuffer
为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
StringBuilder 提供了一系列插入、追加、改变该字符串里包含 的 字符序 列的方法 。 而 StringBuffer与其用法完全相同,只是 StringBuffer 是线程安全 的 。
StringBuilder 、 StringBuffer 有两个属性 : length 和 capacity , 其中 length 属性表示其包含的字符序列的长度。与 String 对象的 length 不同的 是:StringBuilder、 StringBuffer 的 length 是可以改变的,可以通过 length()、 setLength(int len)方法来访 问和修改其字符序列的长度。 capacity 属性表示 StringBuilder的容量, capacity 通常比 length 大,程序通常无须关心 capacity 属性。 如下程序示范了 StringBuilder 类的用法:
public class StringBuilderTest {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
// 追加字符串
sb.append("java");//sb = "java"
// 插入
sb.insert(0 , "hello "); // sb="hello java"
// 替换
sb.replace(5, 6, ","); // sb="hello,java"
System.out.println(sb);
// 删除
sb.delete(5, 6); // sb="hellojava"
System.out.println(sb);
// 反转
sb.reverse(); // sb="avajolleh"
System.out.println(sb);
System.out.println(sb.length()); // 输出9
System.out.println(sb.capacity()); // 输出16
// 改变StringBuilder的长度,将只保留前面部分
sb.setLength(5); // sb="avajo"
System.out.println(sb);
}
}
Math 类
Java 提供了基本的+、一、 *、 /、%等基本算术运算的运算符,但对于更复杂的数学运算 ,例如,三角函数、对数运算、指数运算等则无能为力 。 Java 提供了 Math 工具类来完成这些复杂的运算, Math类是一个工具类,它的构造器被定义成 private 的, 因此无法创建 Math 类的对象 ; Math 类中的所有方法都是类方法,可以直接通过类名来调用它 们 。 Math 类除提供 了大量静态方法之外,还提供了两个类变量 : PI 和 E , 正如它们名 字所暗示的,它们的值分别等于π平日 e 。
下面程序示范了 Math 类 的用法 。
public class MathTest {
public static void main(String[] args) {
/* ------下面是三角运算-------- */
// 将弧度转换成角度
System.out.println(" Math.toDegrees(1.57): " + Math.toDegrees(1.57));
// 将角 度转换为弧度
System.out.println(" Math.toRadians (90): " + Math.toRadians(90));
// 计算反余弦,返回的角度范围在 0 . 0 到 pi 之间
System.out.println(" Math . acos(1 . 2): " + Math.acos(1.2));
// 计算反正弦,返回的角度范围在 -p工 /2 到 pi/2 之间
System.out.println(" Math.as 工 n(0.8 ): " + Math.asin(0.8));
// 计算反正切,返回的角度范围在 -pi/2 到 pi /2 之间
System.out.println("Math . atan(2.3): " + Math.atan(2.3));
// 计算三角余弦
System.out.println("Math . cos(1 . 57): " + Math.cos(1.57));
// 计算双 曲余弦
System.out.println(" Math . cosh(1 . 2 ): " + Math.cosh(1.2));
// 计算正弦
System.out.println(" Math.sin(1.57 ): " + Math.sin(1.57));
// 计算双曲正弦
System.out.println(" Math . sinh(1 . 2 ): " + Math.sinh(1.2));
// 计算三角正切
System.out.println("Math . tan(0 . 8 ): " + Math.tan(0.8));
// 计算双曲正切
System.out.println("Math . tanh(2 . 1 ): " + Math.tanh(2.1));
// 将矩形坐标 (x , y) 转换成极坐标 (r , thet))
System.out.println("Math . atan2(0.1 , 0 . 2): " + Math.atan2(0.1, 0.2));
/* -----下面是取整运算 -------- */
// 取整 ,返回小于目标数的最大整数
System.out.println("Math.floor( - 1 . 2 ): " + Math.floor(-1.2));
// 取整 ,返回大于目标数的最小整数
System.out.println("Math.ceil(I.2) : " + Math.ceil(1.2));
// 四舍五入取整
System.out.println("Math . round(2.3 ) : " + Math.round(2.3));
/*------下面是乘方、开方、指数运算-----*/
// 计算平方根
System.out.println("Math . sqrt(2.3 ): " + Math.sqrt(2.3));
// 计算立方根
System.out.println("Math . cbrt(9 ): " + Math.cbrt(9));
// 返回欧拉数 e 的 n 次幕
System.out.println("Math .exp(2 ): " + Math.exp(2));
// 返回 sqrt(x2 +y2) ,没有中间溢出或下溢
System.out.println("Math.hypot (4 , 4 ): " + Math.hypot(4, 4));
// 按照 IEEE 754 标准的规定,对两个参数进行余数运算
System.out.println("Math . IEEEremainder(5 , 2): " + Math.IEEEremainder(5, 2));
// 计算乘方
System.out.println("Math .pow (3, 2 ): " + Math.pow(3, 2));
// 计算自然对数
System.out.println(" Math.log(12 ): " + Math.log(12));
// 计算底数为 10 的对数
System.out.println("Math . logl0 ( 9) : " + Math.log10(9));
// 返回参数与 1 之和的自然对数
System.out.println("Math.loglp ( 9) : " + Math.log10(9));
/*------下面是符号相关的运算 ----------*/
// 计算绝对值
System.out.println(" Math . abs(-4.5): " + Math.abs(-4.5));
// 符号赋值 ,返回带有第二个浮点数符号的第一个浮点参数
System.out.println("Math . copySign(I.2 , -1 . 0) : " + Math.copySign(1.2, -1.0));
// 符号 函数,如果参数为 0 ,则返回 0: 如果参数大于 0
// 则返回1. 0 ; 如果参数小于 0 ,则返回 - 1. 0
System.out.println(" Math . sig口 um (2. 3): " + Math.signum(2.3));
/*-----下面是大小相关的运算----- */
// 找出最大值
System.out.println("Math.max(2 . 3 , 4.5) : " + Math.max(2.3, 4.5));
// 计算最小值
System.out.println("Math . min(I . 2 , 3 . 4) : " + Math.min(1.2, 3.4));
// 返回第 一个参数和第二个参数之间与第一个参数相邻的浮点数
System.out.println("Math.nextAfter(l . 2 , 1.0) :" + Math.nextAfter(1.2, 1.0));
// 返回比目标数略大的浮点数
System.out.println("Math . nextUp(l . 2 ): " + Math.nextUp(1.2));
// 返回 一个伪随机数,该值大于等于 0 . 0 且小于1. 0
System.out.println("Math. randorn (): " + Math.random());
}
}
API:java.lang.Math
参考:
【1】:《疯狂Java讲义》
【2】:https://www.liaoxuefeng.com/wiki/1252599548343744/1260469698963456