Java——String类

String 是一种常见的引用数据类型,字符串的应用也比较广泛。今天就为大家详细地介绍一下String 类。

目录

常用方法

1.字符串构造

2.String 对象的比较

字符串常量池

1.字符串常量池

2.String 对象的创建

字符串的不可变性

StringBuilder 和 StringBuffer


常用方法

1.字符串构造

String 类提供的构造方式有很多,常用的有以下四种:

public static void main(String[] args){
    // 1.使用常量串构造
    String s1 = "hello world";

    // 2.直接 new String 对象
    String s2 = new String("hello world");

    // 3.使用字符数组进行构造
    char[] arr = {'h','e','l','l','o',' ','w','o','r','l','d'};
    String s3 = new String(arr);
    System.out.println(s3);

    // 4.调用字符串的静态方法 valueOf 来产生对象
    String s4 = String.valueOf("hello world");
}

【注意】

1.String 是引用类型,内部并不会存储字符串本身,

2.在 Java 中 “” 引起来的也是 String 类型对象,例如:

// 打印 “hello” 字符串的长度
// 1,2的结果是相同的
String str = "hello";
System.out.println(str.length());        // 1
System.out.println("hello".length());    //2

2.String 对象的比较

字符串的比较是常见的一种操作,比如,字符串排序。Java中总共提供了 4 种方法

1.== 比较是否引用同一个对象(只看地址,不看内容)

与基本数据类型不同的是,==比较基本数据类型时,计较的是变量中的值,而比较引用数据类型时比较的是变量的地址。

public static void main(String[] args){
    int a = 10;
    int b = 20;
    int c = 10;

    // 比较基本类型    
    System.out.println(a == b);    //false
    System.out.println(a == c);    //true

    // 比较引用类型
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("world");
    String s4 = s1;
    
    System.out.println(s1 == s2);    //false
    System.out.println(s2 == s3);    //false
    System.out.println(s1 == s3);    //false
    System.out.println(s1 == s4);    //true
}

2.boolean equals(Object anObject)方法:按照字典序比较(大小写敏感,返回值是布尔类型)

还有一个方法 boolean equalsIgnoreCase(Object anObject),这个方法也是按照字典序进行比较,但是大小写不敏感,返回值也是布尔类型

比较的是两个对象是否相等

字典序:字符大小的顺序

String 类中重写了 Object 中的 equals 方法,Object 中 equals 方法默认是按照 == 进行比较的,所以在 String 重写 equals 方法的时候要按照如下的规则进行重写:

public boolean equals(Object anObject){
// 1.先检测 this 和 anObject 是否为同一个对象,如果是,返回 true
    if(this == anObject){
        return true;
    }
// 2.检测 anObject 是否为一个 String 类型的对象,如果是,继续比较,如果不是,返回 false
    if(anObject instanceof String){
        String antherString = (String)anObject;
        int n = value.length;
    // 3.this 和 anObject 两个字符串长度是否相同,是的话继续比较,不是的话返回 false
        if(n == antherString.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 trur;
        }
    }
    return false;
}

举例: 

public static void main(String[] args) {
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("Hello");

    // s1、s2、s3引用的是三个不同对象,他们的地址不同,因此 == 比较结果全部为false
    System.out.println(s1 == s2); // false
    System.out.println(s1 == s3); // false

    // equals比较:String对象中的逐个字符
    // 虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true
    // s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出false
    System.out.println(s1.equals(s2)); // true
    System.out.println(s1.equals(s3)); // false
}

3. int compareTo(String s)方法:按照字典序进行比较

还有一个方法是int compareToIgnoreCase(String str),这个方法与int compareTo(String s)方法是一样的,只是忽略大小写比较

比较的是两个对象的大小

与 equals 不同的是,这个方法的返回值类型是整型。

比较的具体方式是:

1.先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值

2.如果前 k 个字符相等(k 为两个字符长度最小值,返回两个字符串长度差值)

举例: 

public static void main(String[] args) {
    String s1 = new String("abc");
    String s2 = new String("ac");
    String s3 = new String("abc");
    String s4 = new String("abcdef");
    System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
    System.out.println(s1.compareTo(s3)); // 相同输出 0
    System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}

如果想了解更多关于对象比较的知识,可以跳转Java对象的比较这篇博客阅读哦~

4. 字符串查找

字符串查找也是字符串中常见的一种操作,String 类提供的常用查找的方法有:

方法功能
char charAt(int index)返回 index 位置上的字符,如果 index 为负数或者越界,抛出 IndexOutOfBoundsException 异常
int indexOf(int ch)返回 ch 第一次出现的位置,没有则返回 -1
int indexOf(int ch,int fromIndex)从 fromIndex 位置开始找 ch 第一次出现的位置,没有则返回 -1
int indexOf(String str)返回 str 第一次出现的位置,没有则返回 -1
int indexOf(String str,int fromIndex)从 fromIndex 位置开始找 str 第一次出现的位置,没有则返回 -1
int lastIndexOf(int ch)从后往前找,返回 ch 第一次出现 的位置,咩有则返回 -1
int lastIndexOf(int ch,int fromIndex)从 fromIndex 位置开始找,从后往前找 ch 第一次出现的位置,没有则返回 -1
int lastIndex(String str)从后往前找,返回 str 第一次出现的位置,没有则返回 -1
int lastIndexOf(String str,int fromIndex)从 fromIndex 位置开始做找,从后往前找 str 第一次出现的位置,没有则返回 -1
boolean contains(CharSequence s)判断字符串中是否有制定字符串,若有则返回true,没有则返回 false

举例:

public static void main(String[] args){
    String s = "aaabbbcccaaabbbccc";
    System.out.prnitln(s.charAt(3));    // 'b'
    System.out.prnitln(s.indexOf('c'));    //6
    System.out.prnitln(s.indexOf('c',10);    //15
    System.out.prnitln(s.indexOf("bbb"));    //3
    System.out.prnitln(s.indexOf("bbb",10));    //12
    System.out.prnitln(s.lastIndexOf('c'));    //17
    System.out.prnitln(s.lastIndexOf('c',10));    //8
    System.out.prnitln(s.lastIndexOf("bbb"));    //12
    System.out.prnitln(s.lastIndexOf("bbb",10));    //3
    System.out.prnitln(s.contains("aaa"));    // true
}

5.转化

5.1数值与字符串转化

public static void main(String[] args) {
    // 数字转字符串
    String s1 = String.valueOf(1234);
    String s2 = String.valueOf(12.34);
    String s3 = String.valueOf(true);
    String s4 = String.valueOf(new Student("Hanmeimei", 18));
    System.out.println(s1);
    System.out.println(s2);
    System.out.println(s3);
    System.out.println(s4);

    // 字符串转数字
    int data1 = Integer.parseInt("1234");
    double data2 = Double.parseDouble("12.34");
    System.out.println(data1);
    System.out.println(data2);
}

5.2大小写转化(只转化字符串中字母部分,对其他形式的字符没有影响)

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "HELLO";
    
    // 小写转大写
    System.out.println(s1.toUpperCase());    // HELLO
    
    // 大写转小写
    System.out.println(s2.toLowerCase());    // hello
}

5.3字符串转数组

public static void main(String[] args){
    String s = "hello";
    // 字符串转数组
    char[] ch = s.toCharArray();
    for(int i = 0;i < ch.length;i++){
        System.out.print(ch[i] + ' ');    // h e l l o 
    }
    // 数组转字符串
    String s2 = new String(ch);
    Syste.out.println(s2);    // "hello"
}

5.4格式化

public static void main(String[] args) {
    String s = String.format("%d-%d-%d", 2023,05,05);    // 2023-05-05
    System.out.println(s);
}

6.字符串替换

使用一个指定的字符串对已有的字符串进行替换,有以下两种方法:

方法功能
String replaceAll(String regex,String replacement)替换所有指定内容
String replaceFirst(String regex,String replacement)替换一个次出现的指定内容

这两个方法中,regex是想要替换的子串内容,replacement是替换后的内容

举例:

String str = "hello";
System.out.println(str.replaceAll('l','a'));    // 结果为 "heaao"
System.out.println(str.replaceFirst('l','a'));    // 结果为 "healo"

【注意】因为字符串具有不可变性,所以这里的替换并不是在原有的字符串基础上进行修改,而是产生了一个新的字符串。

7.字符串拆分

将一个字符串按照规定拆分为几部分,有以下两种方法:

方法功能
String[] split(String regex)将字符串全部拆分
String[] split(String regex,int limit)将字符串以指定的格式,拆分为 limit 组

举例:

// 全部拆分
String str = "hello world hello bit" ;
    String[] result = str.split(" ") ; // 按照空格拆分
    for(String s: result) {
        System.out.println(s);
    }
// 结果为  hello
//        world
//        hello 
//        bit

// 拆分为 2 组
String str = "hello world hello bit" ;
    String[] result = str.split(" ",2) ; // 按照空格拆分
    for(String s: result) {
        System.out.println(s);
    }
// 结果为 hello
//        world hello bit

【注意】

1.用字符“|”,“*”,“,”,“+”进行拆分时,前面要加上“\\”进行转义

2.如果是“\”,就要写成“\\\”

3.如果一个字符串中由多个分隔符,可以用“|”作为连字符。

8.字符串截取

从一个完整的字符串总截取出部分内容,有以下两种方法:

方法功能
String substring(int beginIndex)从指定索引截取到结尾
String substring(int beginIndex,int endIndex)截取部分内容

举例:

String str = "helloworld";
System.out.println(str.substring(5));    // world
System.out.println(str.substring(0, 5));    // hello

【注意】

1.索引从 0 开始

2.截取部分内容的时候,是左闭右开区间

9.其他方法

String trim():起吊字符串中的左右空格,保留中间空格

String str = "  hello world   ";
System.out.println("["+str+"]");    // [  hello world   ]
System.out.println("["+str.trim()+"]");    // [hello world]

字符串常量池

1.字符串常量池

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
}

在上边的代码中,我们可以看到 s1 和 s2 引用的是同一个对象,但是  s3 和 s4 引用的却不是同一个对象,这是为什么呢?其实在 Java 程序中,为了使程序的运行速度更快、更节省内存, Java 为 8 中基本数据类型和 String 类都提供了常量池。

那么什么是常量池呢?

“池”是编程中的一种常见的,重要的提升效率的方法,在以后的学习中我们还会学到“线程池”,“内存池”等。

为了节省存储空间以及程序的运行效率,Java 引入了:
1.Class 文件常量池:在每一个 .Java 源文件变以后生成 .Class文件中会保存当前类中的字面常量以及符号信息。

2.运行是常量池:在 .Class 文件被加载时,.Class 文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份。

3.字符串常量池

下面我们为大家简单介绍一下字符串常量池:

字符串常量池在 JVM 中时 StringTable 类,实际上是一个固定大小的HashTable,不同 JDK 版本下字符串常量池的位置以及默认大小是不同的:

JDK 版本字符串常量池位置大小设置
Java6(方法区)永久代固定大小:1009
Java7堆中可设置,没有大小限制,默认大小:60013
Java8堆中可设置,有范围限制,最小是1009

【注意】只有直接赋值的方式才会用到常量池!

2.String 对象的创建

1.直接使用字符串常量进行赋值

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "hello";
    System.out.println(s1 == s2); // true
}

【说明】

1.在字节码文件加载时,“hello” 长良川已经创建好了,并且保存在字符串常量池中

2.当使用 String s1 = “hello”,创建对象时,现在字符床常量池中找,找到了就将该字符串引用赋值给 s1

2.通过 new 创建 String 类对象 

public static void main(String[] args) {
    String s1 = "hello";
    String s2 = "hello";

    String s3 = new String("world");
    String s4 = new String("world");
}

【结论】只要是 new 创建的对象,就一定是唯一的。

通过上面的例子可以看出:使用长良川创建 String 类对象的效率更高,也更节省空间。

3.intern 方法

intern 方法是一个 native 方法,native 方法是指:底层用C++实现,看不到其实现的源代码。

该方法会将创建的 String 对象添加到常量池中。

public static void main(String[] args) {
    char[] ch = new char[]{'a', 'b', 'c'};
    String s1 = new String(ch);  // s1对象并不在常量池中
    s1.intern();                 // 调用之后,会将s1对象的引用放入到常量池中
    String s2 = "abc";           // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
    
    // 如果没有 s1.intern() 方法,这个输出应该是 false;
    // 但是有了 s1.intern() 方法,这个输出就是 true;
    System.out.println(s1 == s2);
}

字符串的不可变性

String 是一种不可变对象,字符串中的内容是不可改变的。原因如下:

1.String 类在设计时就是不可改变的

在 String 类的源码中有这个一句话

除此之外,还有

从图中,不仅可以看出 String 类对象不可被修改,还可以发现 String 类被 final 修饰,所以 String 类不能被继承。

【注意】字符串不可变不是因为 String 类自身,或者其内部 value 被 final 修饰而不能被改变, final 修饰类表明该类不想被继承, final 修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容可以被修改,不能修改的是这个引用指向不变。

2.所有涉及到可能修改字符串内容的方法,其本质都不是修改字符串本身,而是重新创建了一个新的对象

比如:replace()方法:

StringBuilder 和 StringBuffer

由于 String 的不可变性,为了方便字符串的修改,Java还提供了 StringBuilder 和 StringBuffer 类。这两个类的大部分功能是相同的,最大的区别是 StringBuilder 线程不安全,但是效率高;StringBuffer 线程安全,但是效率低

这里我主要介绍一下 StringBuffer 类的常用方法,如果想了解更详细可以参考以下两个文件:

StringBuffer 在线文档             StringBuilder 在线文档

方法说明
public StringBuffer append(String s)将指定的字符串追加到此字符序列
char charAt(int index)返回此序列中指定索引处的char值
int length()返回字符串长度
int capacity()返回底层保存字符串空间总的大小
void ensureCapacity(int minimumCapacity)确保容量至少等于指定的最小值。
void setCharAt(int index, char ch)将给定索引处的字符设置为 ch
int indexOf(String str)返回第一次出现的指定子字符串在该字符串中的索引
int indexOf(String str, int fromIndex)从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引
StringBuffer insert(int offset, String str)str 参数的字符串插入此序列中
StringBuffer delete(int start, int end)删除[start,end)区间内的字符
StringBuffer replace(int start, int end, String str)将[start,end)位置的字符替换为 str
String substring(int start)从 start 开始一直到末尾的字符以 String 的方式返回
String substring(int start, int end)

将[start,end)范围内的字符以 String 的方式返回

StringBuffer reverse()将此字符序列用其反转形式取代。
String toString()将所有字符按照 String 的方式返回

StringBuffer 和 String 的相互转换:

  • String 变为 StringBuffer :利用 StringBuffer 的构造方法或者使用 append() 方法
  • StringBuffer 变为 String:调用 tostring() 方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值