Java字符串String学习与使用(常用核心类)

目录

字符串String简单介绍:

一、字符串的特点:

二、字符串对象的创建方式:

1.使用字符串字面量 

2.使用String类的构造器

3.使用字符串+其他类型

三、String类的常用方法

1、系列1

2、系列2:查找

3、系列3:字符串截取

4、系列4:和字符相关

5、编码相关

练习题:字符串内存分析

四、StringBuilder&StringBuffer

1. 与String区别

2. 常用API


纯手写,转发请带出处。如有帮助请一键三连给予动力。


字符串String简单介绍:

Java中的String是一个引用数据类型,表示字符串,String也是一个类,位于java.lang包下。

创建一个对象,在main方法中:

new String();

因为字符串特别常用,所以Java提供了简短的字符串字面量的表示方式,字面量"abc"也表示String类的实例,如:

String s = "abc";

 这里"abc"即为String类型的对象。

一、字符串的特点:

1.字符串对象的不可变性:字符串是常量,字符串对象一旦创建后,内容不可改变。

        即,字符串内容不同,一定不是同一个字符串对象。


2.String类 底层 使用char[]来存储字符数据。JDK9之后改为byte[]。

        查看字符串类源码,,这里看前两行:

public final class String;  --->>   public(公共)final(最终,不可修改)的String类

private final char value[]; --->>    private(私有)final(最终,不可修改)的char类型value[]数组

 注意这里使用的私有、不可变的数组,由此源码也可以很好的解释上文中提到的“不可变”原因。String类型中存放了一个value,而这里的value存放的是数组的地址值(引用数据类型),value又是final修饰的,即代表数组地址值不可变、不可修改。但是,从理论上来讲数组里的内容可以修改。可这里加了私有, 无法调用,又是final类,无法继承,并且类里也没有任何方法调用,所以字符串一旦创建,字符串对象的内容无法修改。

 3.字符串字面量"abc"存储在字符串常量池中,并且内容相同的字符串在这个池中只有一份。

        如 s1 = "abc"  s2 = "abc"  , 那么s1一定等于s2。

String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); //true

4.String类是final修饰的不能被继承。

二、字符串对象的创建方式:

1.使用字符串字面量 

        类名 变量名 = "对象";

String s1 = "abc";


2.使用String类的构造器

这里具体可以翻阅API构造方法摘要(部分已过时),我放几个较为常见的:

① public String():初始化新创建的 String对象,以使其表示空字符序列。

String s2 = new String(); //空字符串
s2 = ""; //简写 ,等同于把空字符串值赋给this.value

 源码:

public String() {
        this.value = "".value;
    }

② String(String original):初始化一个新创建的 `String` 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。

String s3 = new String("hello");
s3 = "hello";//简写

③ public String(char[] value): 通过当前参数中的字符数组来构造新的String。

char[] chs = {'a', 'b', 'c'};
String s4 = new String(chs);
System.out.println("s4 = " + s4); // s4 = abc

④ public String(char[] value,int offset, int count): 通过字符数组的一部分来构造新的String。

//这里沿用上面的chs数组,取2位,即下标0a和1b
String s5 = new String(chs, 0, 2);
System.out.println("s5 = " + s5);//s5 = ab

如果超出字符串长度,则字符串越界,提示java.lang.StringIndexOutOfBoundsException

⑤ public String(byte[] bytes): 通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。

byte[] bys = {97, 98, 99};
String s6 = new String(bys);
System.out.println("s6 = " + s6);//s6 = abc

⑥ public String(byte[] bytes,String charsetName): 通过使用指定的字符集解码当前参数中的字节数组来构造新的String。

String s7 = new String(bys,"UTF-8");
System.out.println("s7 = " + s7); // s7 = abc

3.使用字符串+其他类型

String s8 = "" + 123;
System.out.println("s8 = " + s8); // s8 = 123

三、String类的常用方法

1、系列1

(1)boolean isEmpty():字符串是否为空

s = null;
s = "";
System.out.println("是否为空: " + s.isEmpty()); //true

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

s = "a";
System.out.println("长度: " + s.length()); //1

(3)String concat(xx):拼接,等价于+ 

String s1 = s.concat("world");
System.out.println("拼接: " + s1); //aworld

(4)boolean equals(Object obj):比较字符串是否相等,区分大小写 

System.out.println(s.equals("hello"));//false
System.out.println("hello".equals(s));//false //建议的使用方式

(5)boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写

System.out.println(s.equalsIgnoreCase("Hello"));//true

(6)int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小 

int i = s.compareTo("HELLO");
System.out.println("i = " + i);//32

(7)int compareToIgnoreCase(String other):比较字符串大小,不区分大小写 

System.out.println(s.compareToIgnoreCase("HELLO"));//0

(8)String toLowerCase():将字符串中大写字母转为小写 

s = "HEllo";
String s1 = s.toLowerCase();
System.out.println("s1 = " + s1);//hello

(9)String toUpperCase():将字符串中小写字母转为大写 

String s2 = s.toUpperCase();
System.out.println("s2 = " + s2);//HELLO

(10)String trim():去掉字符串前后空白符 

s = "  abc  ";
System.out.println(s.length());//7,空格算1个
String s1 = s.trim();
System.out.println("s1 = " + s1);//abc
System.out.println("s1 = " + s1.length());//3

2、系列2:查找

String s = "hello world";

(11)boolean contains(xx):是否包含xx 

System.out.println(s.contains("wo"));//true

(12)int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1 

int index = s.indexOf("l");
System.out.println("index = " + index);//index = 2

(13)int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1 

int lastIndexOf = s.lastIndexOf("o");
System.out.println("lastIndexOf = " + lastIndexOf);//lastIndexOf = 7

            int indexOf(String xx,int from);//从指定位置from开始查找xx,返回第一次出现的位置,如果没有返回-1 

int index2 = s.indexOf("o", 5);
System.out.println("index2 = " + index2);//index2 = 7

3、系列3:字符串截取

String s = "hello world";

(14)String substring(int beginIndex) :返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。 

String substring = s.substring(2);
System.out.println("substring = " + substring);

(15)String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。 

String substring1 = s.substring(2, 4);//[2,4)
System.out.println("substring1 = " + substring1);

练习题:

String str = "我是中国人, 中国的首都是北京,中国有长江黄河,中国最高的山峰是珠穆朗玛峰,拉萨是中国最高的城市。";

String s = "中国";

求str中s出现的次数

 @Test
    public void test88(){
        String str = "我是中国人, 中国的首都是北京,中国有长江黄河,中国最高的山峰是珠穆朗玛峰,拉萨是中国最高的城市。";
        String s = "中国";

        int index = str.indexOf(s);//索引值,从0开始
        int count = 0;//统计目标字符串的个数,累计相加
        while (index != -1){//0不等于-1,开始执行
            count++; //统计次数+1
            index += s.length();//查找到后加上s的长度,用于 计算新的查找起始位置
            index = str.indexOf(s, index);//查找下一个目标字符串的位置
        }
        System.out.println("count = " + count);

    }

4、系列4:和字符相关

String s = "hello world";

(16)char charAt(int index):返回[index]位置的字符 

char c = s.charAt(0);
System.out.println("c = " + c);//h

(17)char[] toCharArray(): 将此字符串转换为一个新的字符数组返回 

char[] chars = s.toCharArray();
System.out.println(chars);//hello world 值得注意的是这里打印的并不是地址,而是通过输出语句把地址里的值挨个输出

(18)String(char[] value):返回指定数组中表示该字符序列的 String。
(19)String(char[] value, int offset, int count):返回指定数组中表示该字符序列的 String。
(20)static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String 

String s1 = String.copyValueOf(chars);
System.out.println("s1 = " + s1);//s1 = hello world

(21)static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String
(22)static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String
(23)static String valueOf(char[] data)  :返回指定数组中表示该字符序列的 String 

String s2 = String.valueOf(chars);
System.out.println("s2 = " + s2);//s2 = hello world

5、编码相关


编码:把字符数据转换为字节数据
解码:把字节数据转换为字符数据

String s = "abc中国";

24)byte[] getBytes():编码,把字符串变为字节数组,按照平台默认的字符编码进行编码 

byte[] bytes = s.getBytes();//使用平台默认的UTF-8编码把字符转换为对应的字节数据
for (int i = 0; i < bytes.length; i++) {
    System.out.print(bytes[i]+" ");
}
System.out.println();

//    byte[] getBytes(字符编码方式):按照指定的编码方式进行编码
byte[] bytes = s.getBytes("GBK");

(25)new String(byte[] ) 或 new String(byte[], int, int):解码,按照平台默认的字符编码进行解码 

String s1 = new String(bytes);//使用平台默认的UTF-8编码把字节数组转换为字符串
System.out.println("s1 = " + s1);
//​    new String(byte[],字符编码方式 ) 或 new String(byte[], int, int,字符编码方式):解码,按照指定的编码方式进行解码
String s2 = new String(bytes, "GBK");
System.out.println("s2 = " + s2);

练习题:字符串内存分析

public class Demo {
    @Test
    public void test1() {
        String s = "hello";//存储在字符串常量池
        String s1 = "hello";//存储在字符串常量池
        String s2 = new String("hello");//在堆中创建新的字符串对象
        String s3 = new String("hello");//在堆中创建新的字符串对象

        System.out.println(s == s1);//true
        System.out.println(s == s2);//false
        System.out.println(s2 == s3);//false
    }

    @Test
    public void test2() {
        String s = "hello";
        String s1 = "world";

        String s2 = "helloworld";
        String s3 = s + s1;//两个字符串使用+连接,其中一个是变量结果一定创建新的字符串对象
        String s4 = s + "world";//在堆中创建新的字符串对象
        String s5 = "hello" + "world";//编译器优化为"helloworld"

//        System.out.println(s2 == s3);//false
//        System.out.println(s2 == s4);//false
//        System.out.println(s2 == s5);//true

        String s6 = new String("hello") + s1;
        String s7 = new String("hello") + new String("world");

//        System.out.println(s2 == s6);//false
//        System.out.println(s2 == s7);//false

        final String s8 = "hello";
        final String s9 = "world";
        String s10 = s8 + s9;
//        String s10 = "hello" + "world";
        System.out.println(s2 == s10);//true

        final String s11 = new String("hello");
        String s12 = s11 + "world";
        System.out.println(s2 == s12);//false

    }
    
}

图解:

字符串的intern方法:返回字符串对象的规范化表示形式。在字符串常量池中保存一份内容相同的字符串。


    @Test
    public void test3(){
//        String s = "hello";
//        String s1 = s.intern();
//        System.out.println(s == s1);//true

        String s2 = new String("wo") + new String("rld");//字符串常量池中没有"world"
//        String ss = "world";
        String s3 = s2.intern();//调用intern方法,把s2的引用存入常量池并返回
        System.out.println(s2 == s3);//JDK8之后是true;JDK7之前是false

//        String s4 = new String("world");
//        String ss = "world";
//        String s5 = s4.intern();
//        System.out.println(s4==s5);//false
//        System.out.println(ss==s5);//true

    }

四、StringBuilder&StringBuffer

1. 与String区别

因为String对象是不可变对象,虽然可以共享常量对象,但是对于频繁字符串的修改和拼接操作,效率极低。因此,JDK又在java.lang包提供了可变字符序列StringBuilder和StringBuffer类型。

@Test
public void test(){
    String s = "hello";
    long startTime = System.currentTimeMillis();//记录当前系统时间,毫秒值
    for (int i = 0; i < 10000; i++) {
        s += i;
    }
    long endTime = System.currentTimeMillis();
    System.out.println("耗时:" + (endTime-startTime)+"毫秒");//341
}

StringBuffer:老的,线程安全的(因为它的方法有synchronized修饰),效率低

StringBuilder:线程不安全的,效率高

@Test
public void test1(){
    //创建可变字符串对象
    StringBuilder sb = new StringBuilder();//创建一个空字符串
    System.out.println(sb);
    //修改字符串
    StringBuilder sb1 = sb.append("hello");
    System.out.println(sb == sb1);//true
	//System.out.println(sb);
    sb.append("world");
    System.out.println(sb);
    sb.append("java").append("html");
    System.out.println(sb);
    //翻转字符串
    sb.reverse();
    System.out.println(sb);
    //转换为String对象
    String s = sb.toString();
    System.out.println(s);
}

2. 常用API

常用的API,StringBuilder、StringBuffer的API是完全一致的

(1)StringBuffer append(xx):拼接,追加

(2)StringBuffer insert(int index, xx):在[index]位置插入xx

(3)StringBuffer delete(int start, int end):删除[start,end)之间字符

StringBuffer deleteCharAt(int index):删除[index]位置字符

(4)void setCharAt(int index, xx):替换[index]位置字符

(5)StringBuffer reverse():反转

(6)void setLength(int newLength) :设置当前字符序列长度为newLength

(7)StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str

(8)int indexOf(String str):在当前字符序列中查询str的第一次出现下标

int indexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的第一次出现下标

int lastIndexOf(String str):在当前字符序列中查询str的最后一次出现下标

int lastIndexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的最后一次出现下标

(9)String substring(int start):截取当前字符序列[start,最后]

(10)String substring(int start, int end):截取当前字符序列[start,end)

(11)String toString():返回此序列中数据的字符串表示形式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别晃我的可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值