Java Review (二十、基础类库----常用类:Object、String、StringBuffer、StringBuilder、Math)

简介: 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 修饰,因此该方法只能被子类重写或调用。

CloneTest.java

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 所指向的对 象在内存中的存储示意图如图所示 。

Object 类提供的克隆机制

image.png

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 类的用法:

StringBuilderTest.java

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); 
  }
}

API:java.lang.StringBuilder

API:java.lang.StringBuffer

Math 类

Java 提供了基本的+、一、 *、 /、%等基本算术运算的运算符,但对于更复杂的数学运算  ,例如,三角函数、对数运算、指数运算等则无能为力 。 Java 提供了 Math 工具类来完成这些复杂的运算,  Math类是一个工具类,它的构造器被定义成 private 的, 因此无法创建 Math 类的对象 ; Math  类中的所有方法都是类方法,可以直接通过类名来调用它 们 。 Math 类除提供 了大量静态方法之外,还提供了两个类变量 : PI 和 E ,  正如它们名 字所暗示的,它们的值分别等于π平日 e 。

下面程序示范了 Math 类 的用法 。

MathTes.java

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


目录
相关文章
|
20天前
|
安全 Java 编译器
JAVA泛型类的使用(二)
接上一篇继续介绍Java泛型的高级特性。3. **编译时类型检查**:尽管运行时发生类型擦除,编译器会在编译阶段进行严格类型检查,并允许通过`extends`关键字对类型参数进行约束,确保类型安全。4. **桥方法**:为保证多态性,编译器会生成桥方法以处理类型擦除带来的问题。5. **运行时获取泛型信息**:虽然泛型信息在运行时被擦除,但可通过反射机制部分恢复这些信息,例如使用`ParameterizedType`来获取泛型参数的实际类型。
|
20天前
|
安全 Java 编译器
JAVA泛型类的使用(一)
Java 泛型类是 JDK 5.0 引入的重要特性,提供编译时类型安全检测,增强代码可读性和可维护性。通过定义泛型类如 `Box&lt;T&gt;`,允许使用类型参数。其核心原理是类型擦除,即编译时将泛型类型替换为边界类型(通常是 Object),确保与旧版本兼容并优化性能。例如,`Box&lt;T&gt;` 编译后变为 `Box&lt;Object&gt;`,从而实现无缝交互和减少内存开销。
|
缓存 Java API
Java-类库-Guava
 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦。
1490 0
|
Java
Java-类库-Guava-复写的Object常用方法
 在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法。每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这几个方法的工具类, Guava也提供了类似的方式。
953 0
Java-类库-Guava-Throwables类
有时候, 当我们我们捕获异常, 并且像把这个异常传递到下一个try/catch块中。Guava提供了一个异常处理工具类, 可以简单地捕获和重新抛出多个异常。 import java.
1013 0
|
Java
Java-类库-Guava-Bimap
 BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构。   通常情况下,我们在使用Java的Map时,往往是通过key来查找value的,但是如果出现下面一种场景的情况,我们就需要额外编写一些代码了。
1043 0
|
Java Apache Windows
Google的Java常用类库 Guava资料
  java的人应该都知道Apache commons的java常用类库吧,这个Guava和commons一样,封装出一套比jdk本身提供的常用类库强大。既然有了这个这么强大的类库,我们就没必要重复造轮子了。
1763 0
|
Java API
Java经典类库-Guava中的函数式编程讲解
如果我要新建一个java的项目,那么有两个类库是必备的,一个是junit,另一个是Guava。选择junit,因为我喜欢TDD,喜欢自动化测试。而是用Guava,是因为我喜欢简洁的API。Guava提供了很多的实用工具函数来弥补java标准库的不足,另外Guava还引入了函数式编程的概念,在一定程度上缓解了java在JDK1.8之前没有lambda的缺陷,使使用java书写简洁易读的函数式风格的代码成为可能。
905 0
|
5天前
|
存储 监控 Java
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
106 60
【Java并发】【线程池】带你从0-1入门线程池
|
16天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
78 14

热门文章

最新文章