JavaSE基础——常用类1

JavaSE基础——常用类1

一、Object类

java.lang.Object类是Java语言中的根类,即所有类的父类。它当中描述的所有方法子类都可以使用。

如果在类的声明中没有显式地使用extends来指明父类,则该类默认的父类就是java.lang.Object

根据API文档,Object类中包含的方法有11个:

  • toString()方法、equals()方法详细说明

  • hashCode()方法:返回对象的哈希码值。(集合

  • clone()方法:创建并返回对象的副本。

  • getclass()方法
    

    :返回对象所在的类。

    • ``getclass().getSuperclass()方法`:返回对象所在的父类
  • finalize()方法:当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该方法。

    • 垃圾回收机制只回收JVM堆内存里的对象空间。对其他类如数据库连接、输入输出流、Socket连接等无能为力。
    • 垃圾回收具有不可预知性,程序无法精准控制垃圾回收机制的执行。程序员可以通过System.gc()或者Runtime.getRuntime.gc()来通知系统进行垃圾回收,但系统什么时候进行不得而知
    • 垃圾回收机制回收任何对象前,总会让对象调用自身的finalize()方法
    • 可以将对象的引用变量设为null,来表明需要垃圾回收机制回收该对象。
  • notify()方法、 notifyAll()方法、 wait()方法(3个):线程

下面学习几个主要的方法:

1. equals方法

1.1 ==运算符回顾

  • ==是运算符,可以使用在基本数据类型和引用类型的比较
  • 如果比较的是基本数据类型,则比较这两个变量保存的值是否相等,此时与数据类型无关。比如:char类型的10和int类型的10是相等的,因为他们的值相等。
  • 如果比较的是引用类型,则比较的是引用的地址值是否相等。即比较两个引用是否指向同一个对象

1.2 equals方法

  • equals()是一个方法,只能被对象调用,因此只能用于引用类型的比较
  • Object类中的equals()方法==运算符的作用是相同的,即都是比较引用的地址值是否相同,判断是否指向同一个对象
  • String类、包装类、Data类、IO流等都重写了Object类中的equals方法,重写后都是比较两个对象的内容是否相同。
// == 与 equals方法
public class Demo01 {
    public static void main(String[] args) {
        // == 运算符用于数值类型的比较时,比较两个对象存储的值是否相等
        //注意不能比较boolean值
        int a = 65;
        double b= 65.0;
        char c = 65;
        char d = 'A';
        boolean e = true;
        int f = 1;
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a == d);
        System.out.println(c == d);
        //即使数据类型不一致,但由于变量中存储的值时相同的,因此结果都是true
        //System.out.println(e == f); 直接报错,== 不能比较boolean类型和其他数据类型
        System.out.println("************ == 用于引用类型的比较***********");
        // == 用于引用类型的比较时,比较两个引用的地址是否一样,即比较两个引用是否指向同一个对象;
        String s = new String("automan");
        String s1 = new String("automan");
        System.out.println(s == s1);
        Man man = new Man("张三",20);
        Man man1 = new Man("张三",20);
        Man man2 = man;
        System.out.println(man == man1);
        System.out.println(man == man2);
        System.out.println("************ equals方法用于引用类型的比较***********");
        //Object类中的equals方法
        System.out.println("Object类中的equals:" + man.equals(man1));
        //String类中的equals方法
        System.out.println("String类中的equals:" + s.equals(s1));
    }
}
class Man {
    String name;
    int age;
    public Man() {
    }
    public Man(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
---------------------------------------------------
运行结果:
    true
    true
    true
    true
    *********** == 用于引用类型的比较**********
    false
    false
    true
    ********** equals方法用于引用类型的比较*********
    Object类中的equals:false
    String类中的equals:true

1.3 equals方法的重写

一般对于自定义的类,也想用equals方法比较两个对象的内容是否一致,这时就需要重写equals方法

快捷键:Alt + insert 生成equals方法

   @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Man man = (Man) o;
        return age == man.age &&
                Objects.equals(name, man.name);
    }

2. toString方法

  • toString方法默认打印的是对象的虚拟地址值。

    • public String toString() {
              return getClass().getName() + "@" + Integer.toHexString(hashCode());
          }
      
  • String类、包装类、Data类、IO流等都重写了Object类中的toString方法,使得调用此类对象的toString方法,返回对象的内容。

  • 一般对于自定义的类,也想用toString方法比较两个对象的内容是否一致,这时就需要重写toString方法。可以用快捷键:Alt + insert 生成。一般是返回对象的属性等。

import java.util.Date;
public class Demo01 {
    public static void main(String[] args) {
        Man man = new Man("张三",20);
        System.out.println(man);
        System.out.println(man.toString());
        System.out.println("***************");
        String s = "automan";
        System.out.println(s);
        System.out.println(s.toString());
        System.out.println("***************");
        Date date = new Date(456487985695L);
        System.out.println(date);
        System.out.println(date.toString());
    }
}
class Man {
    String name;
    int age;
    public Man() {
    }
    public Man(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
--------------------------------------------------
运行结果:
    com.CommomMethod.www.Man@14ae5a5
    com.CommomMethod.www.Man@14ae5a5
    ***************
    automan
    automan
    ***************
    Tue Jun 19 18:13:05 CST 1984
    Tue Jun 19 18:13:05 CST 1984
    //可以看到打印对象名,实际上也就是在调用对象的toString方法。

toString()方法默认返回对象的字符串表示形式,也就是对象的地址,通过重写toString()方法可以让其返回对象的属性等值。

二、 包装类

1. 包装类简介

一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。但编程中经常会遇到需要使用对象,而不是内置数据类型的情形。

为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。这样基本数据类型就也具有了类的特征。所有的包装类**(Integer、Long、Byte、Double、Float、Short)**都是抽象类 Number 的子类。

包装类基本数据类型
Booleanboolean
Bytebyte
Shortshort
Integerint
Longlong
Characterchar
Floatfloat
Doubledouble

img

public class Demo01 {
    public static void main(String[] args) {
        // 此时自动调用:Integer.valueOf(),若数字大于-128且小于127,直接返回值,否则新建一个对象
        Integer integer1 = 1000;
        Integer integer2 = 1000;
        int i1 = 1000;
        int i2 = 1000;
        // 因为两个变量不是同一个对象因此结果为false
        System.out.println(integer1 == integer2); 
        System.out.println(integer1.equals(integer2));// true
        System.out.println(i1 == i2); // true
        System.out.println(i1 == integer2); // true
    }
}
---------------------------------------------------
运行结果:
    false
    true
    true
    true 
//包装类后也具有类的特征了

2. 包装类、基本数据类型、String类的转换

2.1 基本数据类型转为包装类

调用包装类的构造器

public class Demo01 {
    public static void main(String[] args) {
        //基本数据类型转换为包装类:利用包装类的构造器
        int num1 = 10;
        //System.out.println(num1.toString()); 报错,因为num1是基本数据类型,不能调用类方法
        Integer num2 = new Integer(num1);       //将num1的值作为包装类Integer构造方法的参数,转为包装类对象num2
        System.out.println(num2.toString());    //包装类中的toString方法也是重写过的,输出对象的内容
        Integer num3 = new Integer("123");
        System.out.println(num3.toString());
        //Integer num4 = new Integer("123abc");
        //System.out.println(num4.toString());  由于数字与字母混用出现格式错误
        Float f1 = new Float(12.3f);
        System.out.println(f1);
        Float f2 = new Float("12.3f");
        System.out.println(f2);
        //Float f3 = new Float("12.3abc");
        //System.out.println(f3);                 由于数字与字母混用出现格式错误
        Num num = new Num();
        System.out.println(num.b1);     //当变量是boolean型时,默认值是false
        System.out.println(num.b2);     //当转换为包装类Boolean时,默认值是null
    }
}
class Num {
    boolean b1;
    Boolean b2;
}
-----------------------------------------
运行结果:
    10
    123
    12.3
    12.3
    false
    null

2.2 包装类转换为基本类型

调用包装类方法Value()

public class Demo01 {
    public static void main(String[] args) {
        Integer num1 = new Integer(12);
        double num2 = num1.doubleValue();
        System.out.println(num2 + 1);
    }
}
---------------------------------------------------
运行结果:
    13.0
    13

2.3 自动装箱与自动拆箱

上面学习了包装类与基本数据类型之间的转换,但是在JDK1.5之后加入了自动装箱与自动拆箱的新特性。

一般情况下,包装类的对象是不能进行数值运算的,但由于自动拆箱的存在,包装类在书写上可以和基本数据类型一样加减乘除。

一般情况下,基本数据类型是不可能转换为一个包装类类型的,要借助包装类的构造方法。但是由于自动装箱的存在,在书写上,也可以直接将一个数值赋给一个对象类型的。

因此,下面的书写也是没有问题的:

public class Demo01 {
    public static void main(String[] args) {
        int num1 = 10;
        Integer num2 = new Integer(20);
        Integer num3 = new Integer(30);
        //自动拆箱,包装类对象自动转为基本数据类型进行加减乘除
        System.out.println(num2 + num3);
        //自动封箱,基本数据类型可以赋给包装类对象
        Integer num4 = num1;
        System.out.println(num4.toString());
    }
}
------------------------------------------------
运行结果:
    50
    10

由于自动装箱与自动拆箱的存在,基本数据类型与包装类的区别就不是那么明显了,书写上可以看作是一个类型。

2.4 基本数据类型、包装类转换为String类

由于自动装箱与自动拆箱的存在,基本数据类型与包装类的区别就不是那么明显了,这里将其看作一个整体实现向String类型的转换。

使用String类里的valueOf方法;

2.5 String类转换为基本数据类型、包装类

使用包装类的Paras方法

public class Demo01 {
    public static void main(String[] args) {
        //基本数据类型、包装类转为String类:valueOf方法
        float f1 = 12.3f;
        String s1 = String.valueOf(f1);
        System.out.println(s1);
        Double d1 = new Double(12.5);
        String s2 = String.valueOf(d1);
        System.out.println(s2);
        Boolean b1 = new Boolean(true);
        String s3 = String.valueOf(b1);
        System.out.println(s3);
        System.out.println("*****String类转为基本数据类型、包装类*****");
        //String类转换为基本数据类型、包装类
        String str1 = "123";
        String str2 = "123.5";
        //int num1 = (int)str1;  类对象不能强制转换为基本类型
        //Integer num2 =  (Integer)str1;  类对象要想实现强制转换,转换前后的类必须有父子关系
        Integer num1 = Integer.parseInt(str1);
        Double num2 = Double.parseDouble(str2);
        System.out.println(num1);
        System.out.println(num2);
        String str3 = "true";
        Boolean num3 = Boolean.parseBoolean(str3);
        System.out.println(num3);
        //对于boolean包装类,只要不是true,都转换为false
        String str4 = "true100";
        Boolean num4 = Boolean.parseBoolean(str4);
        System.out.println(num4);
    }
}
--------------------------------------------------
运行结果:
    12.3
    12.5
    true
    *****String类转为基本数据类型、包装类*****
    123
    123.5
    true
    false

3. 一个例子

public class Demo01 {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j);
        //当数值在-128~127范围内,自动封装的引用指向的都是同一个对象(IntegerCache中的Integer[]数组中的值)
        Integer a = 20;
        Integer b = 20;
        System.out.println(a == b);
        //当超出范围,自动封装就是new一个新的对象引用,这时两次封装指向的就是不同的对象
        Integer x = 128;
        Integer y = 128;
        System.out.println(x == y);
    }
}
-----------------------------------------
运行结果:
    false
    true
    false

所有的包装类内部都有一个数组用于存储所指示范围内的数据,因为比较常用,为了提高效率就用了这么一个数组,当自动封装的数据为该范围内的数值时,就直接指向数组内对应的值。

当超出数组范围的数据时,自动封装相当于使用new关键字调用包装类的构造方法,创建一个新对象的引用,这时两次自动封装所指向的对象就不一样了。

三、String类

字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

1. String类简介

  • String类是一个final类,不可被继承
  • String类实现了Serializable接口:表示字符串是支持序列化的(IO流)
  • String类实现了Comparable接口:表示String可以比较大小
  • String类内部定义了final char[] value数组用于存储字符串的数据。也就是说字符串本质是一个字符数组,数组内的每一个元素都是char类型
  • String代表不可变的字符序列。具有不可变性。字符串的值在创建之后不能更改。

2. 创建字符串

创建字符串有两种方式:

  • 直接创建
    • String str = "automan";
  • 利用构造方法创建
    • String str2 = new String("automan")

这两种方法的作用效果是不一样的。字符串常量是存储在方法区的常量池中的。直接创建时,String类的引用在栈中,直接指向常量池中的字符串。利用new创建时,String类引用指向堆中的String类对象,String类对象中存储常量池中的字符串。

public class Demo01 {
    public static void main(String[] args) {
        String str1 = "automan";
        String str2 = "automan";
        System.out.println(str1 == str2);
        String str3 = new String("automan");
        String str4 = new String("automan");
        System.out.println(str3 == str4);
        System.out.println(str1 == str3);
        System.out.println(str2 == str4);
    }
}
----------------------------
运行结果:
    true
    false
    false
    false

img

由上图可见,str1str2引用都是指向常量池中的字符串常量,地址一样,因此==运算符结果为true,而str3存储的时堆中String对象的地址,str4中存储的是堆中String对象的地址,地址不一样,因此==运算结果为false。这也是两种String类实例化方式的区别。

同样的,对于下面程序有:

public class Demo01 {
    public static void main(String[] args) {
        Person p1 = new Person("automan", 20);
        Person p2 = new Person("automan",20);
        Person p3 = new Person(new String("automan"), 20);
        System.out.println(p1.name == p2.name);
        System.out.println(p1.name == p3.name);
    }
}
class Person {
    String name;
    int age;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
-----------------------------------------
运行结果:
    true
    false

3. 连接字符串

String 类提供了连接两个字符串的方法:

  • string1.concat(string2);:返回 string2 连接 string1 的新字符串。也可以对字符串常量使用 concat() 方法
  • 更常用的是使用'+'操作符来连接字符串

不同拼接操作的比较

public class Demo01 {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        String s3 = "helloworld";
        String s4 = "hello" + "world";
        String s5 = "hello" + s2;
        String s6 = s1 + s2;
        String s7 = (s1 + s2).intern();
        System.out.println(s3 == s4);
        System.out.println(s3 == s5);
        System.out.println(s3 == s6);
        System.out.println(s4 == s5);
        System.out.println(s3 == s7);
        //有final修饰的是常量,常量与常量拼接结果在常量池中。
        final String s8 = "world";
        String s9 = "hello" + s8;
        System.out.println(s3 == s9);
    }
}
------------------------------------
运行结果:
    true
    false
    false
    false
    true
    true
  • 常量与常量的拼接,结果也在常量池中,且常量池中不会村次昂相同内容的常量;
  • 只要有一个是变量,结果就在堆中
  • 如果拼接结果调用intern()方法,则返回值是常量池中的结果。

img

4. 一个例子

public class Demo01 {
    String str = new String("good");
    char[] ch = {'t', 'e', 's', 't'};
    public void change(String str, char ch[]) {
        str = "test ok";
        ch[0] = 'b';
    }
    public static void main(String[] args) {
        Demo01 test = new Demo01();
        test.change(test.str, test.ch);
        System.out.println(test.str);
        System.out.println(test.ch);
    }
}
------------------------------
运行结果:
    good
    best

对于原来的存储可以看作是这样的,引用类型作为形参,传递的是地址,因此局部变量和原有变量指向的是同一个对象

img

当执行change方法后:

img

change内的操作使得局部变量str指向的对象改变,但原来str指向的没有改变。change内的操作使得堆里面char[]数组的的第一个元素指向改变,因此原来ch指向的char[]数组内容发生了变化。

这也是String字符串不可变性的体现

5.String类中的常用方法

常用方法作用
length()返回字符串长度
boolean isEmpty()判断字符串是否为空。
toLowerCase()使用默认语言环境,将String中所有字符转为小写
toUpperCase()使用默认语言环境,将String中所有字符转为大写
concat(String str)将指定的字符串连接到该字符串的末尾
equals(Object obj)将此字符串与指定对象进行比较
equalsIgnoreCase(Object obj)将此字符串与指定对象进行比较,忽略大小写
endsWith(String suffix)测试字符串是否以指定后缀结束
startsWith(String prefix)测试字符串是否以指定前缀开始
startsWith(String prefix,int toffset)测试该字符串从指定索引开始的子字符串是否以指定前缀开始
indexOf(String str)返回指定子字符串在该字符串中第一次出现时的索引
indexOf(String str, int fromIndex)从指定索引开始,返回指定子字符串在该字符串中第一次出现时的索引
lastIndexOf(String str)返回指定子字符串在该字符串中最后一次出现时的索引
lastIndexOf(String str, int fromIndex)从指定索引开始反向搜索,返回指定子字符串在该字符串中最后一次出现时的索引
contains(CharSequence s)当且仅当字符串中包含指定的char值序列时,返回true

6. String与字符数组的转换

  • String转换为字符数组
    • 使用String类中的toCharArray方法
  • 字符数组转为String
    • 调用String的构造器
//将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg”
public class Demo01 {
    public static void main(String[] args) {
        String str = "a21cb3";
        //此处给定的值是字符数组的索引值
        System.out.println(reverse(str,1,4));
    }
    public static String reverse(String str, int begin, int end) {
        if (str != null) {
            char[] ch = str.toCharArray();
            for (int i = begin, j = end; i < j; i++, j--) {
                char temp = ch[i];
                ch[i] = ch[j];
                ch [j] = temp;
            }
            return new String(ch);
        }
        return null;
    }
}
--------------------------------------
运行结果:
    abc123

7. String与字节数组的转换

  • String转换为字符数组
    • 使用String类中的getBytes方法
  • 字符数组转为String
    • 调用String的构造器
public class Demo01 {
    public static void main(String[] args) {
        String str1 = "abc123中国";
        //使用默认的字符集进行转换,这里默认的是UTF-8编码集
        byte[] b = str1.getBytes();
        System.out.println(Arrays.toString(b));
        String s = new String(b);
        System.out.println(s);
    }
}
------------------------------------------
运行结果:
   [97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]
    abc123中国
    //对于汉字,UTF-8编码用三个字节表示一个汉字

String与字节数组的转换经过了编码与解码的过程,编码与解码时的字符集要一致。

四、StringBuffer 和 StringBuilder 类

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

1. String类、StringBuffer 和 StringBuilder 类比较

  • String类: 不可变的字符序列
  • StringBuffer类:可变的字符序列,线程安全,效率低
  • StringBuilder类:可变的字符序列,线程不安全,效率高
  • 三个类都是关于字符串的类,底层都是使用char[] 数组存储字符串内容。

关于String类的不可变:

String字符串是不可变的字符列,有如下特点:

String str1 = "hello";    //相当于在常量池中有一个"hello",将str1指向的该字符串常量;
str1 = "hello" + "world"; //这就会在常量池中新建一个"helloworld"常量,将str1引用指向这个新的字符串常量,原来的"hello"依然存在。
str1 = "mm"; //这就会在常量池中新建一个"mm"常量,将str1引用指向这个新的字符串常量,原来的"hello"和"helloworld"依然存在。
//这些留下来的字符常量就交给垃圾回收,当没有引用指向它们时,JVM认为它们无用了就会回收释放空间。

但是 StringBuffer 和 StringBuilder 类不一样,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象

StringBuffer sb1 = "hello";    //相当于在常量池中有一个"hello",将sb1指向的该字符串常量;
sb1 = "hello" + "world"; //还是常量池中原有的那个"hello",会在其底层的char[]数组后面加上"world",还是将sb1指向常量池中的这个字符串,但字符串内容变了。不会产生新的字符串常量。
sb1 = "mm"; //还是在常量池中的那个字符串常量,将其底层的char[]数组内的元素变为mm,不产生新的字符串常量。

由此可已看出StringBuffer类的字符串长度似乎是“可变”的

分析其源码可以知道,StringBuffer类和StringBuilder 类当创建一个新的空对象时,其底层的char[]数组默认长度是16,也就是说相当于默认创建的是一个长度为16的数组,可以存放16个字符。

当存储的字符串长度超过16时,就需要扩容,根据其源码的设计,默认会新建一个长度为2 * 当前数组长度 + 2的新的字符数组,并将现有字符数组里的内容赋值给新数组。

一般情况下,应该尽量避免扩容(创建新数组并复制元素,当数据量较大时,速度较慢),因此应该预判会用到多长的数组,在创建新对象时,使用有参的构造方法确定字符串长度。此时底层的数组的长度为设定的字符串长度+16

public class Demo01 {
    public static void main(String[] args) {
        String str = new String(); //底层char[] value = new char[0];
        String str1 = new String("abc");//底层char[] value = new char[0]{a, b, c};
        StringBuffer sb1 = new StringBuffer(); //底层char[] value = new char[16];底层创建一个长度为16的数组
        sb1.append('a');    //底层:value[0] = 'a';  相当于把字符依次赋给长度为16的字符数组
        sb1.append('b');    //底层:value[1] = 'b';  相当于把字符依次赋给长度为16的字符数组
        //但此时返回字符串的长度,返回的是往数组内填充的元素的个数,而不是全部的字符数组长度
        System.out.println(sb1.length()); //字符串的长度为2
        StringBuffer sb2 = new StringBuffer("abc");//底层char[] value = new char["abc".length + 16];
    }
}

一般情况下,对于需要修改的字符串,优先选用StringBuffer 和 StringBuilder 类,而不是String类。然后再根据线程安全问题选择是StringBuffer 还是 StringBuilder 类,并预判所需的字符串长度,调用有参的构造方法创建可变的StringBuffer对象或者 StringBuilder 对象。

2. SrtingBuffer类的常用方法

方法作用
append(xxx)类似于字符串拼接,再已有字符串后面填充xxx
delete(int start, int end)删除指定区域内的字符
replace(int start, int end, String str)替代指定范围内的字符为str
insert(int offset, xxx)再指定位置插入xxx
reverse()把当前字符序列逆转
indexOf(String str)返回str再当前字符串中首次出现的位置
substring(int start,int end)返回一个start到end的左闭右开的子字符串(切片)
length()返回字符串长度
charAt(int n )返回指定索引处的字符
setCharAt(int n ,char ch)将指定位置的字符改为ch
  • 当使用append方法和insert方法时,若原有value长度不够,可扩容。
  • 上述方法都支持方法链操作

总结:

  • 增:append(xxx)
  • 删:delete(int start, int end)
  • 改:setCharAt(int n ,char ch)replace(int start, int end, String str)
  • 查:`charAt(int n )
  • 插:insert(int offset, xxx)
  • 长度:length()
  • 遍历:for循环 + charAt(int n )

3. StringBuilder类

StringBuilderStringBuffer非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样

4. 三者效率对比

public class Demo01 {
    public static void main(String[] args) {
        //初始设置
        long startTime = 0L;
        long endTime = 0L;
        String text = "";
        StringBuffer buffer = new StringBuffer("");
        StringBuilder builder = new StringBuilder("");
        //开始对比
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间:" + (endTime - startTime));
    }
}
----------------------
运行结果;
    StringBuffer的执行时间:5
    StringBuilder的执行时间:3
    String的执行时间:1493
        

转载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值