关于Java中的String类

关于Java中的String类(JDK8)

1.理解

1.1 String 类的声明

public final class String implements java.io.Serializable, Comparable<String>, CharSequence{
    private final char value[];//String类一旦初始化后,地址就不可变(jdk8)
    private final byte value[];//jdk9及以后,为了节省内存空间;官方:大多数String类声明时都用的是拉丁字符,只用byte的空间就已经足够
} 
//Serializable:可序列化的接口(通过网络和数据流来传输数据)
//Comparable:可以比较大小的接口

1.2 字符串常量存储的位置

1.2.1 常量池
public class StringTest{
	public static void main(String args[]){
        String s1 = "hello";//可以用字面量定义的方式初始化String类的对象
        String s2 = "hello";
        System.out.println(s1==s2);//output:true
        //同一字符串常量在常量池中的地址相同
    }
}

1.3 String类的不可变 性

public class StringTest2{
	public static void main(String args[]){
        String s1 = "hello";
        String s2 = "hello";
        s2 = "hi";
        System.out.println(s1);//output:hello
        //对字符串常量重新赋值时,需要指定另外一个地址并赋值相应的字符串常量,此例中s2的地址改变,指向了hi在常量池中的地址
    }
}
public class StringTest3{
	public static void main(String args[]){
        String s1 = "hello";
        String s2 = "hello";
        s2 += "hi";
        System.out.println(s1);//output:hello
        //对字符串常量进行拼接操作时,也要另外开辟一个地址
        //使用replace()函数和拼接“+”时同理
    }
}

2.String类的实例化

public class StringTest{
    public static void main(String args[]){
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");
        
        System.out.println(s1==s2);//true
        System.out.println(s1==s3);//false
        System.out.println(s3==s4);//false
        System.out.println(s1==s4);//false
        
        System.out.println(s1.equals(s2));//true
    }
}

一道经典的面试题:

String s3 = new String(“hello”);这个语句创建了几个对象?

答:2个。一个是new出来的s3,一个是创建在字符串常量池中字面量“hello”

//intern()方法返回的是字符串常量池的地址
String s1 = "helloworld";
String s2 = "hello";
String s3 = "world";
String s4 = s2+s3;
System.out.println(s1=s4.intern());//true

3.String类的构造器

public class StringTest{
    public static void main(String args[]){
        String s1 = new String();
        String s2 = new String("");//s1和s2相同
        
        String s3 = new String(new char[]{'a','b','c'});
        System.out.println(s3);//abc     
    }
}

4.String类的常用方法

4.1 String类与其他类型的转换方法

//String类--->char[]:
String str = "hello";
char[] arr = str.toCharArray();
for(int i = 0;i<arr.length;i++){
    System.out.println(arr[i]);
}

//char[]--->String类
String s3 = new String(new char[]{'a','b','c'});
System.out.println(s3);//abc

//String类--->byte[]
//注意:utf-8中,中文字符占3个字节,英文字符占1个字节
//GBK中,中文字符占2个字节,英文字符占1个字节
String str = "abc中国";
byte arr[] = str.getBytes();//使用默认字符集:utf-8
for(int i = 0;i<arr.length;i++){
    System.out.println(arr[i]);//输出ASCII码值
}

//getBytes(String charsetName)
String str1 = "abc中国";
byte arr1[] = str1.getBytes("gbk");
for(int i = 0;i<arr.length;i++){
    System.out.println(arr[i]);//输出ASCII码值
}

//byte[]--->String类
//涉及到解码和编码
//解码:将ascii码转换成String
String str2 = new String(arr,"utf-8");
System.out.println(str2);//解码,将ascii码值转换为String

String str3 = new String(arr,"gbk");//使用了不一样的字符集
System.out.println(str3);//乱码

String str4 = new String(arr1,"gbk");//byte arr1[] = str1.getBytes("gbk");
System.out.println(str4);//正常输出

4.2 重要的API

1.boolean isEmpty();//判断字符串是否为空,注意null不能调用(空指针异常)
2.int length();
3.String concat(xx);//拼接
4.boolean equals(Object obj)//区分大小写
5.boolean equalsIgnoreCase(Object obj);//不区分大小写
6.int compareTo(String other);//用unicode编码大小一位一位地比
7.int compareToIgnoreCase(String other);//忽略掉大小写
8.String toLowerCase();//返回全小写
9.String toUpperCase();//返回全大写
10.String trim();//削去字符串中的空格
11.public String intern();//结果在常量值中共享
12.boolean contains(xx);//是否包含xx
13.int indexOf(xx)//返回第一次找到xx的下标,如果没找到就返回-1
14.int indexOf(String str, int fromIndex);//从指定的索引开始往后找
15.int lastIndexOf(xx);//从后往前找xx
16.int lastIndexOf(String str, int fromIndex);//从指定的索引开始往前找
17.String subString(int beginIndex);//返回从指定索引开始之后的字符串(包括索引处)
18.String subString(int beginIndex, int endIndex);//返回两个指定索引之间的子字符串(左闭右开)
19.char charAt(index);//返回index位置的字符
20.char[] toCharArray();//见笔记前面
21.static String valueOf(char[] data);//char[]--->String类
22.static String valueOf(char[] data, int offset, int count);//用指定的角标和长度截取data转换为字符串
23.static String copyValueOf(char[]data);
24.static String copyValueOf(char[]data, int offset, int count);
25.boolean startsWith(xx);//判断一个字符串是否是以xx开头
26.boolean startsWith(String prefix, int toffset);//指定索引
27.boolean endsWith(xx);//判断一个字符串是否是以xx结尾
28.String replace(char oldChar, char newChar);
29.String replace(CharSequence target, CharSequence replacement);//使用另一个字符串替代指定的
30.String replaceAll(String regex, String replacement);//regex--正则表达式
31.String replaceFirst(String regex, String replacement);//

5. StringBuffer / StringBuilder

5.1 String / StringBuffer / StringBuilder三个类的比较

String :不可变的字符序列

StringBuffer : 可变的字符序列;jdk1.0,线程安全

StringBuilder:可变的字符序列;jdk5.0,线程不安全

5.2 StringBuffer / StringBuilder可变性分析

//针对于StringBuffer
//内部的属性有:
char[] value;//没有final,可变
int count;//“实际”存储的字符个数,不包括源码中预留的16个字符

StringBuilder s1 = new StringBuilder();//源码中:char[] value = new char[16];预留了16个字符的位置,为xx了append()方法留下足够的空间
StringBuilder s1 = new StringBuilder("abc");//char[] value = new char[16+"abc".length()];
s1.append("ab");//value[0]='a';value[1] = 'b'
s1.append("c");//value[2]='c'

//不断地append(),如果超过了16个字符,那么就要扩容,并扩容到原来内存大小的2倍+2,并将原来value中的值赋给新的数组

5.3 StringBuffer/StringBuilder的常用方法

增:
1.StringBuffer append(xx);
删:
1.delete(int start, int end);//左闭右开
2.deleteCharAt(int index);
改:
1.replace(int start, int end, String str);
2.setCharAt(int index, char c);
查:
1.charAt(int index);
插入:
insert(int index, xx);
其他:
length();
StringBuffer reverse();

5.4 三者效率比较

StringBuilder(线程不安全,不需要握锁)>StringBuffer(线程安全,需要握锁)>String

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值