二十五、String与StringBuffer/StringBu

2018-08-21  本文已影响18人  圣贤与无赖

一、 String类

1. String类概述

查阅API中的String类的描述,发现String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
继续查阅API发现说字符串是常量;它们的值在创建之后不能更改,这是什么意思呢?其实就是说一旦这个字符串确定了,那么就会在内存区域的常量池中就生成了这个字符串。字符串本身不能改变,但str变量中记录的地址值是可以改变的。
继续阅读API发现,因为 String 对象是不可变的,所以可以共享,这又是什么意思呢?其实就是说由于字符串一旦生成,在常量池中是不可变的,那么不管有多少个引用,只要他们的引用的字符串相同,即就是这些引用指向同一片内存区域。
继续查API发现,字符串有大量的重载的构造方法。通过String类的构造方法可以完成字符串对象的创建,那么,通过使用双引号的方式创建对象与new的方式创建对象,有什么不同呢?看如下程序与图解:

String s3 = "abc";
String s4 = new String("abc");
System.out.println(s3==s4);//false
System.out.println(s3.equals(s4));//true,
//因为String重写了equals方法,建立了字符串自己的判断相同的依据(通过字符串对象中的字符来判断)

s3和s4的创建方式有什么不同呢?
 s3创建,在内存中只有一个对象。这个对象在字符串常量池中
 s4创建,在内存中有两个对象。一个new的对象在堆中,一个字符串本身对象,在字符串常量池中

2. String类构造方法

构造方法是用来完成String对象的创建,下图中给出了一部分构造方法需要在API中找到,并能够使用下列构造方法创建对象。


String构造方法.png
String s1 = new String(); //创建String对象,字符串中没有内容
    
    byte[] bys = new byte[]{97,98,99,100};
    String s2 = new String(bys); // 创建String对象,把数组元素作为字符串的内容
    String s3 = new String(bys, 1, 3); //创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数length为要几个元素
    
    char[] chs = new char[]{’a’,’b’,’c’,’d’,’e’};
    String s4 = new String(chs); //创建String对象,把数组元素作为字符串的内容
    String s5 = new String(chs, 0, 3);//创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数count为要几个元素

    String s6 = new String(“abc”); //创建String对象,字符串内容为abc

3. String类的常用方法

长度 是否为空 前缀 比较

将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。

切割

split() 方法根据匹配给定的正则表达式来拆分字符串。
参数
regex -- 正则表达式分隔符。
limit -- 分割的份数。
返回值
字符串数组。

注意: . 、 | 和 * 等转义字符,必须得加 \。
注意:多个分隔符,可以用 | 作为连字符。

语法
public String[] split(String regex, int limit)

实例:

public class Test {
    public static void main(String args[]) {
        String str = new String("Welcome-to-Runoob");
 
        System.out.println("- 分隔符返回值 :" );
        for (String retval: str.split("-")){
            System.out.println(retval);
        }
 
        System.out.println("");
        System.out.println("- 分隔符设置分割份数返回值 :" );
        for (String retval: str.split("-", 2)){
            System.out.println(retval);
        }
 
        System.out.println("");
        String str2 = new String("www.runoob.com");
        System.out.println("转义字符返回值 :" );
        for (String retval: str2.split("\\.", 3)){
            System.out.println(retval);
        }
 
        System.out.println("");
        String str3 = new String("acount=? and uu =? or n=?");
        System.out.println("多个分隔符返回值 :" );
        for (String retval: str3.split("and|or")){
            System.out.println(retval);
        }
    }
}

以上程序执行结果为:

按字典顺序比较

按字典顺序比较两个字符串。该比较基于字符串中各个字符的 Unicode 值。按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。如果这两个字符串相等,则结果为 0;compareTo 只在方法 [equals(Object)] 返回 true 时才返回 0
这是字典排序的定义。如果这两个字符串不同,那么它们要么在某个索引处的字符不同(该索引对二者均为有效索引),要么长度不同,或者同时具备这两种情况。如果它们在一个或多个索引位置上的字符不同,假设 k 是这类索引的最小值;则在位置 k 上具有较小值的那个字符串(使用 < 运算符确定),其字典顺序在其他字符串之前。在这种情况下,compareTo 返回这两个字符串在位置 k 处两个char 值的差,即值:

this.charAt(k)-anotherString.charAt(k)

如果没有字符不同的索引位置,则较短字符串的字典顺序在较长字符串之前。在这种情况下,compareTo 返回这两个字符串长度的差,即值:

this.length()-anotherString.length()

getBytes()

实例:

import java.io.*;
 
public class Test {
    public static void main(String args[]) {
        String Str1 = new String("runoob");
 
        try{
            byte[] Str2 = Str1.getBytes();  //无参数表示使用默认字符集
            System.out.println("返回值:" + Str2 );
            
            Str2 = Str1.getBytes( "UTF-8" );
            System.out.println("返回值:" + Str2 );
            
            Str2 = Str1.getBytes( "ISO-8859-1" );
            System.out.println("返回值:" + Str2 );
        } catch ( UnsupportedEncodingException e){
            System.out.println("不支持的字符集");
        }
    }
}

以上程序执行结果为:
返回值:[B@7852e922
返回值:[B@4e25154f
返回值:[B@70dea4e

hashcode()

返回此字符串的哈希码。String 对象的哈希码根据以下公式计算:
s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希值为 0。)

其他常用方法:

查位置1 查位置2 替换 截取 转换为char数组 大小写转换 去掉首位空白 连接 判断是否包含

将其他类型变量转换为String


将其他类型变量转换为String

char数组转换为String字符串


char数组转换为String

字符串转数组


String转char数组

二、StringBuffer类

StringBuffer又称为可变字符序列,它是一个类似于 String 的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。
原来StringBuffer是个字符串的缓冲区,即就是它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。
可将字符串缓冲区安全地用于多个线程。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

无论多少数据,数据是什么类型都不重要,只要最终变成字符串就可以使用StringBuffer这个容器。
实例:int[] arr = {34,12,89,68};将一个int[]中元素转成字符串 格式 [34,12,89,68]

public static String toString_2(int[] arr) {
        StringBuffer sb = new StringBuffer();       
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if(i!=arr.length-1){
                sb.append(arr[i]+",");
            }else{
                sb.append(arr[i]+"]");
            }
        }       
        return sb.toString();
    }

每个字符串缓冲区都有一定的容量(长度等于字符串长度+16,只创建对象为16)。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 [StringBuilder]。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

1. StringBuffer构造方法摘要

stringbuffer构造方法

2. StringBuffer的方法使用

Stringbuffer常用方法.png

代码演示:

创建一个字符串缓冲区对象。用于存储数据。
StringBuffer sb = new StringBuffer();
sb.append("haha"); //添加字符串
sb.insert(2, "it");//在指定位置插入
sb.delete(1, 4);//删除
sb.replace(1, 4, "cast");//替换指定范围内的内容
String str = sb.toString();

注意:append、delete、insert、replace、reverse方法调用后,返回值都是当前对象自己,所以说,StringBuffer它可以改变字符序列的长度和内容。

stringbuffer的其他方法


stringbuffer的其他方法

3. 对象的方法链式调用

在我们开发中,会遇到调用一个方法后,返回一个对象的情况。然后使用返回的对象继续调用方法。这种时候,我们就可以把代码现在一起,如append方法一样,代码如下:
创建一个字符串缓冲区对象。用于存储数据。
StringBuffer sb = new StringBuffer();
添加数据。不断的添加数据后,要对缓冲区的最后的数据进行操作,必须转成字符串才可以。
String str = sb.append(true).append("hehe").toString();

上一篇下一篇

猜你喜欢

热点阅读