零基础Java第二十期:认识String(二)

发布于:2024-12-06 ⋅ 阅读:(31) ⋅ 点赞:(0)

 

目录

 一、String的常用方法

1.1. 去除左右两边的空白

 1.2. intern方法

1.3. 字符串的不可变性 

1.4. 字符串修改

二、StringBuilder和StringBuffer

2.1. StringBuilder的介绍 

2.2. append方法

2.3. capacity方法 


一、String的常用方法

1.1. 去除左右两边的空白

       使用trim方法会去掉字符串开头和结尾的空白字符,比如空格、换行、回车、制表符、翻页符等空白字符都可以去除。这个方法针对用户输入时的场景,比如,用户再搜索框里面输入了一些空格,一般属于无意义的数据,trim方法就能提高“容错性”。

public class Main {
    public static void main(String[] args) {
        String str = new String("\t\t\thello\n\n\n");
        System.out.print(str);
        System.out.print(str.trim());
    }
}

String str1 = "hello";//字面值常量,本身就在池中
char[] arrays = {'h','e','l','l','o'};
String str2 = new String(arrays);
System.out.println(str1 == str2);

 1.2. intern方法

       某些字符串常量我们需要经常使用,intern方法可以帮助我们把字符串常量手动入池中。这样能帮助我们优化程序的效率,也能降低程序内存的开销。 

String str1 = "hello";//字面值常量,本身就在池中
char[] arrays = {'h','e','l','l','o'};
String str2 = new String(arrays);
String str3 = str2.intern();

System.out.println(str1 == str2);
System.out.println(str1 == str3);

      上面的代码中,str2字符串因为在池外,str1在池内,所以说str2与str1所指向的地址不同。

public native String intern();

       JVM我们来看一下intern的源码,可以看到这个方法没有实现,并且还有一个native关键字,这样的方法称之为“本地方法”。这样的方法没有在Java中实现,而是在JVM上实现的。JVM本体是由C++编写的,要想看到这里的逻辑实现,就需要下载JVM源码。

1.3. 字符串的不可变性 

       String类是不能修改的,所有的修改都会创建新对象,效率非常低下。这里的修改是对象本体不能修改,而不是String的引用不能修改。

 

       为啥String是不可变的呢?我们来看一下String里面的源码,可以看到里面的字节数组被private修饰。针对这个数组,String没有提供public方法。那为啥要把String设计成不可修改呢?1. 方便实现字符串对象池,如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了;2. 不可变对象是线程安全的。3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中。

//String的源码
private final byte[] value;

1.4. 字符串修改

public class Main {
    public static void main(String[] args) {
        String str = "hello";
        str += " world";
        System.out.println(str);//结果为“hello world”
    }
}

     但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。我们还可以使用StringBuffer或者StringBuilder。

二、StringBuilder和StringBuffer

2.1. StringBuilder的介绍 

方法 说明
StringBuff append(String str) 在尾部追加,相当于String的+=,可以追加
char charAt(int index) 获取index位置的字符
int capacity() 获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity) 扩容
void setCharAt(int index, char ch) 将index位置的字符设置为ch
int indexOf(String str) 返回最后一次出现str的位置
int indexOf(String str, int fromIndex) 从fromIndex位置开始查找str第一次出现的位置

 博主在这里只重点介绍一下append和capacity方法

2.2. append方法

//这里没有创建一个新的对象
StringBuilder str1 = new StringBuilder("hello");
str1.append(" world");
System.out.println(str1);

    下面博主会用一个例子来带你更直观地感受StringBuilder的优势。

public class Main {
    public static void main(String[] args) {
        String str1 = "";//空字符串
        StringBuilder str2 = new StringBuilder("");
        int time = 10_000;
        //获取时间戳
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            str2.append(i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("时间: " + (endTime - startTime));
        main2(args);
    }

//每次都创建新的对象
    public static void main2(String[] args) {
        String str1 = "";//空字符串
        StringBuilder str2 = new StringBuilder("");
        int time = 10_000;
        //获取时间戳
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            str1 += i;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("时间: " + (endTime - startTime));
    }

 

    注意,这里打印出来的结果单位是毫秒。 

2.3. capacity方法 

public class Main {
    public static void main(String[] args) {
        StringBuilder str1 = new StringBuilder("hello");
        System.out.println(str1.capacity());//容量是21

        str1.ensureCapacity(128);
        System.out.println(str1.capacity());//修改之后的容量是128
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到