JavaSe之字符串String

字符串

字符串的类:

1、String

2、StringBuffer(线程安全)

3、StringBuilder

1、String

public final class String implements ... {
    /** The value is used for character storage. */
    private final char value[];
   
    private int hash; // Default to 0

    private static final long serialVersionUID = -6849794470754667710L;

    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];
}

1.1String特点

1.1不可变的字符串

private final char value[]; 其核心成员变量char数组被final修饰,无法改变。String也随之是一个不可变的字符串;

String str=“abc”;

str = "abc "+ “d”;

字符串是不可变的,str开始是“abc"字符串对象的引用,str=“abc”+“d”;产生三块内存空间

1.2字符串的创建

//第一种:通过new关键字,通过构造方法
public String() {this.value = "".value;};
public String(byte[]bytes , Charset charset);//指定编码的byte数组转换为字符串

//第二种:直接赋值法(推荐)
String var=字符串常量对象; //字符串常量对象: 不仅仅是字符串的值,而且还是一个字符串对象。
//
//第三种:

1.2.1字符串常量池 String pool

关于StringPool的内存位置,JDK7之后将Stringpool从方法区的运行时常量池 移到 堆区

只用来存储字符串常量(双引号修饰的字符串),用来存储运行时产生的各种字符串,且”池中的字符串的内容不可重复

存放一个字符串于字符串常量池:

  1. 从字符串常量池中查找是否存在该字符串
  2. 如果有,直接返回找到的字符串常量中的字符串对象
  3. 如果没有,在字符串常量池创建这个对象
1.2.2 字符串创建的内存结构
        //第一种
        String str1 = new String("hello");
//通过new创建的字符串对象内存开辟:
//(1)先判断字符串常量池中有"hello”这个字符串对象,没有则在字符串常量池中创建
//(2)在堆区创建这个字符串对象,最后引用也指向这块内存空间
        //第二种
        String str2="hello"; 
        String str3="hello";

str2==str3(true)  str1==str2(false)

请添加图片描述

1.2.3 字符串拼接 创建字符串
  • 字符串常量(纯字符串)的拼接

如下案例:字符串常量的拼接,在预编译时+会被优化,(字符串常量池并不会产生"he"和"llo"两个字符串对象,)动拼接成一个.则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

String str1="hello";
String str2="he"+"llo";
str1==str2(true)
  • 含有字符串变量的拼接则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。最后指向堆内存中的对象
String str3="he";
String str4=str3+"llo";  //不仅在String池创建了“he”和“llo”还有	

​ 对于字符串变量的相加(str1+str2),JVM底层使用StringBuilder做了优化 ,本质就是先创建new StringBuilder(),调用append方法进行拼接,最后调用toString(),实际上还是new Stirng()

1.2.4 String对象的两种实例化方式的区别
  • String对象的实例化方式有两种:直接赋值和通过构造器方法完成
  • 直接赋值:只开辟一个堆内存空间,而且采用了共享设计模式,可以自动的入池,以备下次对象继续使用;

  • 构造方法:会开辟两块内存空间,其中有一块空间将成为垃圾,而且不会自动入池,但是可以使用intern()方法进行手工入池;

  • 从开发角度而言,很明显使用直接赋值的方式会更好一些。

1.3 String的操作

1.3.1 字符串的比较
  1. ”==”表示判断该两个字符串是否为同一对象,即在内存中的地址是否一样。如果一样则返回true 否则返回false; 和我们通常的是否为同一对象的是一样的。

  2. boolean equals(ObjectanObject) 将此字符串与指定的对象比较。注意此时比较的是内容是否相等(字符串类对此方法进行了覆写)。

    public boolean equals(Object anObject) {
        //1、先比较内存地址
            if (this == anObject) {
                return true;
            }
        //2、判断类型
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
        //3、判断字符串长度
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
        //4、逐个字符进行判断
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    
  3. boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写。

  4. int compareTo(Stringvalue) 按字典顺序比较两个字符串。如果两个字符串相等,则返回 0;如果字符串在参数值之前,则返回值小于 0;如果字符串在参数值之后,则返回值 大于 0

  5. int compareToIgnoreCase(String val) 按字典顺序比较两个字符串,不考虑大小写

1.3.2字符串的常用方法

1.字符与字符串:
public String(char[] value)--------------------------全部字符数组变为String类
public String(char[] value,int offset,int count)-----部分字符数组变为String
public char charAt(int index)------------------------返回指定位置上的字符
public char[] toCharArray()--------------------------字符串变为字符数组
2.字节数组与字符串:
public String(byte[] bytes)--------------------------全部字节数组变为字符串
public String(byte[] bytes,int offset,int length)----部分字节数组变为字符串
public byte[] getBytes()-----------------------------字符串变为字节数组
public byte[] getBytes(String charsetName)throws UnsupportedEncodingException-----------------转码
3.字符串比较:
public boolean equals(String anObject)---------------字符串内容的比较,区分大小写
public boolean equalsIgnoreCase(String anotherString)不区分大小写完成字符串内容的比较
public int compareTo(String anotherString)-----------判断字符串的大于,小于,等于
4.字符串检索:
public boolean contains(String s)--------------------判断指定的子字符串是否存在
public int indexOf(String str)-----------------------从头查找指定的子字符串是否存在,存在则返回字符串的索引,不存在则返回-1
public int indexOf(String str,int fromIndex)---------从指定位置开始检索,没找到则返回-1
public int lastIndexOf(String str)-------------------从后向前查找字符串的位置
public int lastIndexOf(String str,int fromIndex)-----从指定位置开始由后向前查找
public boolean startsWith(String prefix)-------------判断是否以指定字符串开头
public boolean endsWith(Sting suffix)----------------判断是否以指定字符串结尾
5.字符串替换:
public String replaceAll(String regex,String replacement)满足条件的内容全部替换
public String replaceFirst(String regex,String replacement)替换第一个满足条件的内容
6.字符串截取:
public String subString(int beginindex)--------------从头截取到尾
public String subString(int beginindex,int endindex)-截取中间的部分内容
7.字符串拆分:
public String[] split(String regex)------------------全拆分
public String[] split(String regex,int limit)--------拆分成指定的个数
8.其他方法:
public boolean isEmpty()-----------------------------判断是否是空字符串,不是null
public int length()----------------------------------取得字符串内容的长度
public String toLowerCase()--------------------------所有内容变为小写
public String toUpperCase()--------------------------所有内容变为大写
public String trim()--------------------------------去掉左右空格,中间的无法去掉

StringBuffer/StringBuilder

字符串类:

String:不可变字符串,频繁进行+操作,在堆中创建String对象,效率比较低。原因:String是一个不可变的字符串,效率很低。

想对字符串进行频繁的修改操作,Jdk提供了StringBuffer/StringBuilder.

  • 两者区别:
    • StringBuffer相较于StringBuilder的方法都加了Synchronized同步锁,所以StringBuffer线程安全的。
    • 加锁少不了性能消耗,虽然StringBuilder线程不安全,但是效率高

相关操作(以StringBuffer为例):

1、构造方法
操作介绍
tringBuffer()构造一个没有字符的字符串缓冲区,初始容量为16个字符
StringBuffer(CharSequence seq)构造一个包含与指定的相同字符的字符串缓冲区 CharSequence
StringBuffer(int capacity)构造一个没有字符的字符串缓冲区和指定的初始容量。
StringBuffer(String str)构造一个初始化为指定字符串内容的字符串缓冲区。
2、String有的都有

唯一不一样的是replace (前闭后开)

操作介绍
StringBuffer replace(int start, int end, String str)用指定的String中的字符替换此序列的子字符串中的 String
3、增删改查(对缓存区进行修改)
  1. 追加append(),可以追加任意数据类型,返回StringBuffer(这样写有好处)
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this; //可以实现方法的连写
    }
StringBuffer sb=new StringBuffer();
sb.append("hello").append(" ").append("world"); //方法的连写
2. 指定位置插入insert

请添加图片描述

3.delete删除操作

请添加图片描述

delete(int start, int end) 前闭后开

        StringBuffer sb=new StringBuffer("hello World");
        sb.delete(0,sb.length()-1);
        System.out.println(sb);
        //如何删除最后一个元素
        sb.deleteCharAt(sb.length()-1);
        System.out.println(sb);
4.反转
操作介绍
StringBuffer reverse()导致该字符序列被序列的相反代替。
5.修改指定位置的字符
操作介绍
void setCharAt(int index,char ch)指定索引处的字符设置为 ch
6.字符串反转

StringBuffer reverse() 导致该字符序列被序列的相反代替。

7.修改指定位置的字符
操作介绍
void setCharAt(int index,char ch)指定索引处的字符设置为 ch
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值