Java_认识String类

在 C 语言中已经涉及到字符串了,但是在 C 语言中要表示字符串只能使用字符数组或者字符指针,
可以使用标准库提 供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开
的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java 语言专门提供了 String 类
目录

[一、 常用方法](#一、 常用方法)

[1.1 构造方法](#1.1 构造方法)

[1.2 字符串比较](#1.2 字符串比较)

[1.2.1 == 比较是否引用同一个对象](#1.2.1 == 比较是否引用同一个对象)

[1.2.2 boolean equals(按照字典序比较 )](#1.2.2 boolean equals(按照字典序比较 ))

[1.2.3 int compareTo(String s) 方法: 按照字典序进行比较](#1.2.3 int compareTo(String s) 方法: 按照字典序进行比较)

[1.2.4 int compareToIgnoreCase(String str)](#1.2.4 int compareToIgnoreCase(String str))

[1.3 字符串查找](#1.3 字符串查找)

[1.4 转化](#1.4 转化)

[1.4.1 数值和字符串转化](#1.4.1 数值和字符串转化)

[1.4.2 大小写转换](#1.4.2 大小写转换)

[1.4.3 字符串转数组](#1.4.3 字符串转数组)

[1.4.4 格式化](#1.4.4 格式化)

[1.5 字符串替换](#1.5 字符串替换)

[1.6 字符串拆分](#1.6 字符串拆分)

[1.7 字符串截取](#1.7 字符串截取)

[1.8 其他操作方法](#1.8 其他操作方法)

[1.9 字符串的不可变性](#1.9 字符串的不可变性)

二、StringBuilder和StringBuffer

[2.1 StringBuilder的介绍](#2.1 StringBuilder的介绍)


一、 常用方法

1.1 构造方法

String类提供的构造方式非常多,常用的有以下三种

java 复制代码
public static void main(String[] args) {
        String s1 = "hello world!";
        System.out.println(s1);
        //    直接常量串构造
        String s2 = new String("hellohellohello!");
        System.out.println(s2);
        //new一个
        char[] arr = {'h', 'e', 'l', 'l', 'o'};
        String s3 = new String(arr);
        System.out.println(s3);
        //    使用字符数组构造
    }

需要注意的是String 是引用数据类型,内部并不存储字符串本身


在 Java 中 "" 引起来的也是 String 类型对象。

java 复制代码
 public static void main(String[] args) {
        System.out.println("hello".length());
    }

1.2 字符串比较

Java中提供了4种比较方式

1.2.1 == 比较是否引用同一个对象

因为 String属于引用数据类型,== 比较的是引用的地址

java 复制代码
public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);
    }

1.2.2 boolean equals(按照字典序比较 )

String 类重写了父类 Objectequals 方法,Objectequals 默认按照 == 比较,String 重写

equals 方法

java 复制代码
public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1.equals(s2));
    }

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

String 类中实现了Comparable 接口

实现了 compareTo方法

比较方法类似于C语言 中的strcmp


先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
如果前 k 个字符相等 (k 为两个字符长度最小值 ) ,返回值两个字符串长度差值

java 复制代码
 public static void main(String[] args) {
        String s1 = new String("helloa");
        String s2 = new String("hellob");
        String s3 = new String("hello123456");
        String s4 = new String("hello");
        System.out.println(s1.compareTo(s2));
        System.out.println("================");
        System.out.println(s3.compareTo(s4));
    }

1.2.4 int compareToIgnoreCase(String str)

与compareTo方式相同,但是忽略大小写比较

java 复制代码
   public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("ABC");
        String s3 = new String("ABc");
        String s4 = new String("aBC");
        System.out.println(s1.compareToIgnoreCase(s2));
        System.out.println(s1.compareToIgnoreCase(s3));
        System.out.println(s1.compareToIgnoreCase(s4));
    }

1.3 字符串查找

String 类提供的常用查找的方法:

|--------------------------------------------|---------------------------------------------------------------|
| 方法 | 功能 |
| char charAt(int index) | 返回 index 位置上字符,如果 index 为负数或者越界,抛出 ndexOutOfBoundsException异常 |
| 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 lastIndexOf(String str) | 从后往前找,返回 str 第一次出现的位置,没有返回 -1 |
| int lastIndexOf(String str, int fromIndex) | 从 fromIndex 位置开始找,从后往前找 str 第一次出现的位置,没有返回-1 |

注意:上述方法都是实例方法。
需要具体的对象去引用

1.4 转化

1.4.1 数值和字符串转化

数字转字符串可以使用 valueOf方法

可以看到valueOf是重载方法

java 复制代码
 public static void main(String[] args) {
        String s1 = String.valueOf(123456);
        System.out.println(s1);
        String s2 = String.valueOf(521.2);
        System.out.println(s2);
    }

字符串转数字可以使用

复制代码
Integer.parseInt
复制代码
Double.parseDouble

java 复制代码
 public static void main(String[] args) {
        String s1 = String.valueOf(123456);
        System.out.println(s1);
        String s2 = String.valueOf(521.2);
        System.out.println(s2);
        System.out.println("=============");
        int data1 = Integer.parseInt(s1);
        System.out.println(data1);
        double data2 = Double.parseDouble(s2);
        System.out.println(data2);
    }

1.4.2 大小写转换

复制代码

toUpperCase 转大写

toLowerCase 转小写

java 复制代码
 public static void main(String[] args) {
        String s1 = "abcdefg";
        String s2 = "ABCDEFG";
        System.out.println(s1.toUpperCase());
        System.out.println(s2.toLowerCase());
    }

1.4.3 字符串转数组

可以使用 toCharArray方法

java 复制代码
 public static void main(String[] args) {
        String s1 = "abcdefg";
        char[] chars = s1.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.println(chars[i]);
        }
    }

1.4.4 格式化

java 复制代码
   public static void main(String[] args) {
        String s = String.format("%d-%d-%d", 1111, 1,11);
        System.out.println(s);
    }

1.5 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据

|-------------------------------------------------------|-----------|
| 方法 | 功能 |
| String replaceAll(String regex, String replacement) | 替换所有的指定内容 |
| String replaceFirst(String regex, String replacement) | 替换首个内容 |

java 复制代码
public static void main(String[] args) {
        String str = "hello" ;
        System.out.println(str.replaceAll("l", "_"));
        System.out.println(str.replaceFirst("l", "_"));
    }

由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

1.6 字符串拆分

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

java 复制代码
public static void main(String[] args) {
        String str = "I love Java!";
        String[] strings = str.split(" ");
        for (String string:strings){
            System.out.println(string);
        }
    }
java 复制代码
   public static void main(String[] args) {
        String str = "I love Java!";
        String[] strings = str.split(" ",2);
        for (String string:strings){
            System.out.println(string);
        }
    }

也会出现特殊情况

java 复制代码
public static void main(String[] args) {
        String str = "123.456.789";
        String[] strings = str.split(".");
        for (String string:strings){
            System.out.println(string);
        }
    }

可以看到分割并没有成功
有些特殊字符作为分割符可能无法正确切分 , 需要加上转义
字符 "|" , "*", "+" 都得加上转义字符
对于split 这个方法来说 需要两个**\** 才能表示一个**\**

java 复制代码
   public static void main(String[] args) {
        String str = "123.456.789";
        String[] strings = str.split("\\.");
        for (String string:strings){
            System.out.println(string);
        }
    }

而如果是 "\\" ,那么就得写成 "\\\\"

java 复制代码
 public static void main(String[] args) {
        String str = "123\\456\\789";
        String[] strings = str.split("\\\\");
        for (String string:strings){
            System.out.println(string);
        }
    }

如果一个字符串中有多个分隔符,可以用"|"作为连字符.

java 复制代码
  public static void main(String[] args) {
        String str = "name=12age%15&11";
        String[] strings = str.split("=|%|&");
        for (String string:strings){
            System.out.println(string);
        }
    }

1.7 字符串截取

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

java 复制代码
 public static void main(String[] args) {
        String str = "hello world!";
        System.out.println(str.substring(5));
        System.out.println(str.substring(0,5));
    }

需要注意的是他的区间是左闭右开

substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

1.8****其他操作方法

|---------------|----------------------|
| 方法 | 功能 |
| String trim() | 去掉字符串中的左右空格 , 保留中间空格 |

java 复制代码
 public static void main(String[] args) {
        String str = " hello world! ";
        System.out.println(str);
        System.out.println(str.trim());
    }

trim 会去掉字符串开头和结尾的空白字符 ( 空格 , 换行 , 制表符等 )

1.9 字符串的不可变性

String 是一种不可变对象 . 字符串中的内容是不可改变.
上述所有操作都是在操作完成后产生一个新的对象
而非在字符串上进行修改

java 复制代码
public static void main(String[] args) {
        String str = "hello world!";
        System.out.println(str.toUpperCase());
        System.out.println(str);
    }



String 类中的字符实际保存在内部维护的 value 字符数组中

同时 value数组被 private 修饰 ,也没有提供 set方法
那就无法拿到 value 这个引用
就不能对其中的内容进行修改
String类被 final 修饰,表明该类不能被继承
value被修饰被 final 修饰,表明 value 自身的值不能改变,即不能引用其它字符数组,但是其引
用空间中的内容可以修改。
final 修饰类表明该类不想被继承, final 修饰引用类型表明该引用变量不能引用其他对象,但是其
用对象中的内 容是可以修改的

二、StringBuilderStringBuffer

由于 String 的不可更改特性,为了方便字符串的修改,Java 中供 StringBuilderStringBuffer

类。

java 复制代码
public static void main(String[] args) {
        String str = "hello";
        str += "world!";
        System.out.println(str);
    }

这里看一下这部分代码的底层是怎么执行的

可以看到

底层在执行这段代码的时候其实进行了多部操作

其实这里相当于是这么写

java 复制代码
  public static void main(String[] args) {
        String str = "hello";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.append("world!");
        str = stringBuilder.toString();
        System.out.println(str);
    }

这个过程中出现了 StringBuilder

java 复制代码
   public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String s = "";
        for(int i = 0; i < 10000; ++i){
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("String:" + (end - start));

        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 10000; ++i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer:" + (end - start));

        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder:" + (end - start));
    }

这这一段代码中循环都是个字符串进行拼接

不同的是分别使用String StringBuffer StringBuilder

那么输出的是执行这一个过程需要的时间,单位是毫秒

可以看到

String 类的拼接效率远低于 StringBuffer StringBuilder

且 StringBuffer StringBuilder 之间的差距可以忽略不计

StringBuffer StringBuilder 拼接效率高的原因再与 append方法

再看一下这个代码的底层是怎么执行的

此处对应的是

这个循环

可以看到的是每次进入循环都需要new 一个对象

对应这个循环

可以看到的是他就不需要 new对象了

String 类型就是因为要不停的创建对象销毁对象

造成效率低下
因此:尽量避免对 String 的直接需要,如果要修改建议尽量
使用 StringBuffer 或者 StringBuilder


StringBufferappend 是一个线程安全的方法
同一时间只有一个线程能够执行这个方法
为了保证这个线程安全
所以会有一些资源的消耗
就导致时间会比 StringBuilderappend时间长

2.1 StringBuilder****的介绍

StringBuilderStringBuffer 类。这两个类大部分功能是相同的,这里介绍StringBuilder 常用
的一些方法,

|------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| 方法 | 功能 |
| StringBuff append(String str) | 在尾部追加,相当于 String 的 += ,可以追加: boolean 、 char 、 char[] 、 double、 float 、 int 、 long 、 Object 、 String 、 StringBuff 的变量 |
| char charAt(int index) | 获取 index 位置的字符 |
| int length() | 获取字符串的长度 |
| int capacity() | 获取底层保存字符串空间总的大小 |
| void ensureCapacity(int mininmumCapacity) | 扩容 |
| void setCharAt(int index, char ch) | 将 index 位置的字符设置为 ch |
| 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 最后一次出现的位置 |
| StringBuff insert(int offset, String str) | 在 offset 位置插入:八种基类类型 & String 类型 & Object 类型数据 |
| StringBuffer deleteCharAt(int index) | 删除 index 位置字符 |
| 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 的方式返回 |

StringStringBufferStringBuilder 的区别
String 的内容不可修改, StringBufferStringBuilder 的内容可以修改 .
StringBufferStringBuilder 大部分功能是相似的
StringBuffer 采用同步处理,属于线程安全操作;而 StringBuilder 未采用同步处理,属于线程不
安全操作

相关推荐
WaaTong2 分钟前
Java反射
java·开发语言·反射
咕咕吖3 分钟前
对称二叉树(力扣101)
算法·leetcode·职场和发展
Troc_wangpeng3 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的5 分钟前
解析json导出csv或者直接入库
开发语言·python·json
Envyᥫᩣ19 分钟前
C#语言:从入门到精通
开发语言·c#
九圣残炎36 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge38 分钟前
Netty篇(入门编程)
java·linux·服务器
童先生40 分钟前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu41 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!1 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法