String、StringBuilder、StringBuffer

String

  • 是不可变的,线程安全的,适用于少量数据操作
  • 类被声明为final,意味着它是不能被继承的,private final char value[]
  • 对象创建后会在字符串常量池缓存,如果下次创建同样对象,直接返回缓存的引用
  • 没有提供修改字符串的公共方法,如果修改字符串(replace/subString/toLowerCase)则会创建一个新的对象返回

两种实例化方式:字面量赋值,new关键字 

//创建一个对象放入常量池,s1为变量,ab为字面量

String s1= "ab"; 

//创建两个对象,一个在堆,一个在常量池
String s2 = new String("cd");

//创建一个对象在堆,由于常量池已经有ab 不会在常量池中再创建

String s3 = new String("ab");

String s1="abc"和String s2=new String(“abc”)区别 

String s1="abc",会创建0或1个对象,如果字符串常量池中没有“abc”,则在常量池中直接创建“abc"并让内存地址指向该对象(1个);如果字符常量池中有“abc”,则直接返回地址值(0个)。

String s2=new String(“abc”),会创建1或2个对象,如果字符串常量池中没有“abc”,则在字符串常量池中和堆内存中个创建一个对象,返回堆地址(2个);如果常量池中有“abc”,则只在堆中创建对象并返回堆地址(1个)。 

String对象的“==”和“equals” 

基本数据类型 “==” 比较的是数据值;引用类型 “==” 比较的是地址是否相同。

String作为引用类型,可通过 == 和 equals 来进行比较。

String对象重写了equals方法。

public static void main(String[] args) {
    //创建一个对象放在字符串常量池中
    String s1 = "hello";
    //字符串常量池中已经存在,不需要创建对象
    String s2 = "hello";
    //s1和s2的内存地址相同,所以为true
    ystem.out.println(s1 == s2);
}

public static void main(String[] args) { 
    //在字符串常量池中和堆内存中个创建一个对象
    String x = new String("xyz");
    //常量池中已存在,则只在堆中创建对象并返回堆地址
    String y = new String("xyz");
    //x和y的内存地址不同,返回false
    System.out.println(x == y);

    //String对象重写了equals方法,返回true
    System.out.println(x.equals(y));

    String k =new String("testString");
    //推荐使用"testString".equals(k)
    System.out.println("testString".equals(k));
    //因为如果k为null的话,k.equals(“testString”)就会报空指针异常
    System.out.println(k.equals("testString"));

}
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

String中“+”的实现 

 字符串常量在拼接的过程中,是将String转换成StringBuilder后,使用append方法进行处理的,其实现的原理就是使用StringBuilder.append()。

String a = "Hello";

String b = "World";

String c = a + "," + b;

//反编译为String c = (new StringBuilder()).append(a).append(",").append(b).toString();

不要在for循环中使用+拼接字符

在for循环中,每次都会new一个StringBuilder,然后把String转换成StringBuilder,再进行append,频繁创建对象浪费时间和内存。 

String result = "Hello";

for(int i = 0 ; i < 500 ;i++ ){

        String s=String.valueOf(i);

        result += s;

        //反编译为 result += (new StringBuilder()).append(result).append(s).ttoString();

}

常用方法 

int length() 返回字符串的长度

char charAt(int index) 返回某索引的字符

boolean isEmpty() 判断字符串是否为空字符串

String toLowerCase/toUpperCase() 转换字符串中的字符为小写/大写

String trim() 忽略前导空白和尾部空白返回字符串

boolean equals(Object object) 比较两个字符串内容是否相等

boolean equalsIgnoreCase(String anotherString) 忽略大小比较两个字符串内容是否相等

String concat(String str) 拼接两个字符串,等价于“+”

int compareTo() 比较两个字符串的大小

String subString(int beginIndex) 截取字符串,从beginIndex位置一直到最后

String subString(int beginIndex,int endIndex) 截取字符串,从beginIndex到endIndex

boolean endsWith(String suffix) 测试字符串是否以指定后缀结束

boolean startsWith(String prefix) 测试字符串是否以指定前缀结束

boolean startsWith(String prefix, int toffset) 测试字符串从指定索引开始的,以指定前缀开始

boolean contains(CharSequence s) 当且仅当字符串包含指定char值序列是返回true

int indexOf(String str) 返回指定字符串在此字符串中第一次出现处的索引

int indexOf(String str, int formIndex) 从指定位置索引开始,返回指定字符串在此字符串中第一次出现处的索引

int lastIndexOf(String str) 返回指定字符串在此字符串中最后出现处的索引

int lastIndexOf(String str, int formIndex) 从指定位置索引开始,返回指定字符串在此字符串中最后出现处的索引

String replace(char oldChar, char newChar) 字符替换,用newChar替换oldChar,返回新字符串

String replaceAll(String regex, String replacement)  字符替换,指定字符串替换符合正则表达式的所有子字符串

String replaceFirst(String regex, String replacement) 字符替换,指定字符串替换符合正则表达式的第一个子字符串

boolean matchs(String regex) 判断字符串是否符合给定的正则表达式

String[] split(String regex) 根据指定的正则表达式匹配拆分字符串

String[] split(String regex, int limit) 根据指定的正则表达式匹配拆分字符串,最多不超过limit个,若超了,剩下全部放在最后一个元素中

StringBuilder

  • 是可变的,没有加同步锁,非线程安全的,适用于单线程操作大量数据字符串,性能高
  • 继承AbstractStringBuilder类,char [] value
  • 在原字符串上进行操作(append,insert,delete),避免了每次操作都创建新对象的问题
@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

StringBuffer

  • 是可变的,加同步锁synchronized,线程安全的,适用于多线程操作大量数据字符串,性能低
  • 继承AbstractStringBuilder类,char [] value
  • 在原字符串上进行操作(append,insert,delete),避免了每次操作都创建新对象的问题
@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值