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 类重写了父类 Object 中equals 方法,Object 中equals 默认按照 == 比较,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 修饰引用类型表明该引用变量不能引用其他对象,但是其
引 用对象中的内 容是可以修改的 。

二、StringBuilder和StringBuffer

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

类。

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 。


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

2.1 StringBuilder****的介绍

StringBuilder 和 StringBuffer 类。这两个类大部分功能是相同的,这里介绍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 的方式返回 |

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

相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习