【Java SE语法篇】10.String类

简介: 【Java SE语法篇】10.String类


前言

在程序开发中经常会用到字符串。字符串是指一连串的字符,它是由许多单个字符连接而成的,如多个英文字母所组成的英文单词。字符串可以包含任意字符,这些字符必须包含在一对双引号""之内,例如:“abc”。Java定义了3个封装字符串的类,分别是String类、StringBuffer类和StringBulider类。它们位于java.lang 包中,并提供了一系列操作字符串的方法,这些方法不需要导包就可以直接使用。下面将对String类、StringBuffer类和StringBulider类进行讲解。

1. String类

1.1 字符串的构造

String类提供了构造方法非常多,常用的就以下三种:

public class Main {
    public static void main(String[] args) {
        // 使用常量串构造
        String s1 = "hello";
        System.out.println(s1);
        // 直接new String对象
        String s2 = new String("hello");
        System.out.println(s2);
        // 使用字符数组进行构造
        char[] chars = {'h','e','l','l','o'};
        String s3 = new String(chars);
        System.out.println(s3);
    }
}

其他方法需要用到时,大家参考Java在线文档:String官方文档

【注意】:

  1. String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类实例变量如下:
public class Main {
    public static void main(String[] args) {
        // s1和s2引用的是不同对象  s1和s3引用的是同一对象
        String s1 = new String("hello");
        String s2 = new String("world");
        String s3 = s1; // s3这个引用指向了s1这个引用的对象
        System.out.println(s3); // hello
        System.out.println(s1.length());// 获取字符串的长度
        System.out.println(s1.isEmpty());// 如果字符串长度为0,返回true,否则返回false
        String s4 = "";
        System.out.println(s4.length()); // 0
        System.out.println(s4.isEmpty());// true
}
  1. 内存图:

  1. 在Java中""引起来的也是String类型对象
// 打印"hello"字符串(String对象)的长度
System.out.println("hello".length());// 5

1.2 String对象的比较

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

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

注意:对于内置类型,==比较的是变量中的值;对于引用类型==比较的是引用中的地址。

public class Main {
    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 == s4);   // true
    }
}

2. equals()方法:按照字典序比较

字典序:字符大小的顺序

String类重写了父类Objectequals方法,Objectequals默认按照==比较,String重写equals方法后,按照 如下规则进行比较,比如:s1.equals(s2)

public class Main {
    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
    }
}

【注意】:为什么以下代码输出的结果都是true

答:因为在 Java 中有一块特殊的内存(常量池),存储在堆上。

它的作用是什么呢?

  1. 只要是""双引号括起来的字符串存放在这里。
  2. 存储字符串之前它会找常量池里是否存在这个字符串,如果有就不存放了(常量池不会重复存放相同的值),所以上述代码中s1s2都指向常量池hello的地址。

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

equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:

  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
public class Main {
    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");
        // s1 和 s2 比较大小 s1 > s2 返回大于0的数字 s1 < s2 返回小于0的数字 否则返回0
        // 返回差值就是对应acsii码的差值
        System.out.println(s1.compareTo(s2));   // 不同输出字符差值-1
        System.out.println(s1.compareTo(s3));   // 相同输出 0
        System.out.println(s1.compareTo(s4));   // 前k个字符完全相同,输出长度差值 -3
    }
}

4. 忽略大小写比较

  • equalsIgnoreCase()方法:与equals()方式相同,但是忽略大小写比较。
  • compareToIgnoreCase()方法:与compareTo()方式相同,但是忽略大小写比较。
public class Main {
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("Abc");
        System.out.println(s1.equals(s2)); // false
        System.out.println(s1.equalsIgnoreCase(s2)); // true
        System.out.println(s1.compareTo(s2));//32
        System.out.println(s1.compareToIgnoreCase(s2));// 0
    }
}

1.3 字符串查找

字符串查找也是字符串中非常常见的操作,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 lastIndexOf(String str) 从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndexOf(String str, int fromIndex) 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返 回-1
public class Main {
    public static void main(String[] args) {
        String s1 = new String("hello");
        // 返回字符串对应下标的字符
        System.out.println(s1.charAt(1)); // e
        //返回对应字符出来的下标位置 从头开始查找
        System.out.println(s1.indexOf('e')); // 1
        //返回对应字符出来的下标位置 从指定位置查找
        System.out.println(s1.indexOf('l', 3)); // 3
        // 字符串查找 从一个字符串找另一个字符串
        System.out.println(s1.indexOf("llo")); // 2
        System.out.println(s1.indexOf("ll", 2));// 2
        // 返回对应字符出来的下标位置 从尾开始向前查找
        System.out.println(s1.lastIndexOf('l'));// 3
        // 返回对应字符出来的下标位置 从指定位置向前查找
        System.out.println(s1.lastIndexOf('l', 1));// -1
        System.out.println(s1.lastIndexOf("ll")); // 2
        System.out.println(s1.indexOf("ll", 1));// 2
    }
}

1.4 转换

1. 数值和字符串转化

public class Main {
    public static void main(String[] args) {
        // 数字转字符串
        String s1 = String.valueOf(123);
        System.out.println(s1);
        String s2 = String.valueOf(12.34);
        System.out.println(s2);
        String s3 = String.valueOf(true);
        System.out.println(s3);
        // 字符串转数字
        int num1 = Integer.parseInt("1234");
        System.out.println(num1);
        
        double num2 = Double.parseDouble("12.34");
        System.out.println(num2);
    }
}

2. 大小写转化

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

问题:转化为大写/小写是在原来的字符串上进行修改的?

答:不是!!!,转化为大写/小写之后,是产生了一个新的对象

通过String类源码中的toUpperCase()方法和toLowerCase()方法返回的都是一个新的字符串。

验证:


3. 字符串转数组

public class Main {
    public static void main(String[] args) {
        // 字符串转数组
        String s1 = "hello";
        char[] chars = s1.toCharArray();
        for (char ch  : chars) {
            System.out.println(ch);
        }
        
        // 数组为字符串
        String s2 = new String(chars);
        System.out.println(s2);
    }
}

4. 格式化

public class Main {
    public static void main(String[] args) {
        String s1 = String.format("%d-%d-%d",2021,5,19);
        System.out.println(s1);
    }
}

1.5 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:

方法 说明
String replaceAll(String regex, String replacement) 替换所有的指定内容
String replaceFirst(String regex, String replacement) 替换收个内容
public class Main {
    public static void main(String[] args) {
        String s1 = "abcabcdeabcd";
        System.out.println(s1.replace('a', 'p')); // pbcpbcdepbcd
        System.out.println(s1.replace("ab","haha")); // hahachahacdehahacd
        System.out.println(s1.replaceAll("ab", "uuu")); // uuucuuucdeuuucd
        System.out.println(s1.replaceFirst("ab", "ha")); // hacabcdeabcd
    }
}

1.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

方法 功能
String[] split(String regex) 将字符串全部拆分
String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组
public class Main {
    public static void main(String[] args) {
        String s1 = "name = zhangsan&age = 18";
        String[] strings = s1.split("&");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
        
        String s2 = "Hello handsome hello beautiful give me some attention"; 
        // 帅哥美女点点关注
        String[] strings1 = s2.split(" ",12); 
        // 虽然不能分割12次 但是它能够保证能分割的最大次数 不够就不分了
        for (int i = 0; i < strings1.length; i++) {
            System.out.println(strings1[i]);
        }
    }
}

特殊情况:

public class Main {
    public static void main(String[] args) {
        String s1 = "192.168.1.2";
        String[] strings = s1.split("\\.");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
        System.out.println("=========");
        String s2 = "C:\\APP\\Java\\jdk1.8\\bin\\java.exe";
        String[] strings1 = s2.split("\\\\");
        for (int i = 0; i < strings1.length; i++) {
            System.out.println(strings1[i]);
        }
        System.out.println("=========");
        
        String s3 = "name=zhangsan&age=18";
        String[] strings2 = s3.split("&|=");
        for (int i = 0; i < strings2.length; i++) {
            System.out.println(strings2[i]);
        }
    }
}

【注意事项】:

  1. 字符"|“,”*“,”+“都得加上转义字符,前面加上”\".
  2. 而如果是"“,那么就得写成”\\".
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分:

public class Main {
    public static void main(String[] args) {
        String s1 = "name=zhangsan&age=18";
        String[] strings = s1.split("&");
        for (String x:strings) {
            String[] strings2 = x.split("=");
            for (String x1 :strings2) {
                System.out.println(x1);
            }
        }
    }
}

1.7 字符串的截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

方法 功能
String substring(int beginIndex) 从指定索引截取到结尾
String substring(int beginIndex, int endIndex) 截取部分内容
public class Main {
    public static void main(String[] args) {
        String s1 = "helloworld" ;
        System.out.println(s1.substring(5)); // world
        System.out.println(s1.substring(0, 5)); 
        // hello 包含 0 下标的字符, 不包含 5 下标
    }
}

1.8 其他操作

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

代码案例:trim()方法:

public class Main {
    public static void main(String[] args) {
        String str = "   hello  world   " ;
        System.out.println("["+str+"]");// [   hello  world   ]
        System.out.println("["+str.trim()+"]");// [hello  world]  
    }
}

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

2. StringBuilde 类 和 StringBuffer类

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilderStringBuffer类。这两个类大 部分功能是相同的,这里介绍 StringBuilder常用的一些方法,其它需要用到了大家可参阅 [StringBuilder在线文档](Overview (Java Platform SE 8 ) (oracle.com))

方法 功能
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的方式返回
public class Main {
    public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder("hello");
        StringBuilder sb2 = sb1;
        // 追加:即尾插-->字符、字符串、整形数
        sb1.append(' ');                  // hello
        sb1.append("world");              // hello world
        sb1.append(123);                  // hello world123
        System.out.println(sb1);          // hello world123
        System.out.println(sb1 == sb2);   // true
        System.out.println(sb1.charAt(0));   // 获取0号位上的字符  h
        System.out.println(sb1.length());    // 获取字符串的有效长度14
        System.out.println(sb1.capacity());  // 获取底层数组的总大小
        sb1.setCharAt(0, 'H');     // 设置任意位置的字符 Hello world123
        sb1.insert(0, "Hello world!!!");         // Hello world!!!Hello world123
        System.out.println(sb1);
        System.out.println(sb1.indexOf("Hello"));          // 获取Hello第一次出现的位置
        System.out.println(sb1.lastIndexOf("hello"));  // 获取hello最后一次出现的位置
        sb1.deleteCharAt(0);                               // 删除首字符
        sb1.delete(0,5);                                   // 删除[0, 5)范围内的字符
        String str = sb1.substring(0, 5);                  // 截取[0, 5)区间中的字符以String的方式返回
        System.out.println(str);
        sb1.reverse();                      // 字符串逆转
        str = sb1.toString();               // 将StringBuffer以String的方式返回
        System.out.println(str);
    }
}

从上述例子可以看出:StringStringBuilder最大的区别在于**String的内容无法修改**,StringBuilder的内容可 以修改。频繁修改字符串的情况考虑使用StringBuilder

注意:StringStringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法。
相关文章
|
1天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
12 3
|
5天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
6天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
10天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
11 0
|
10天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
13 0
|
10天前
|
存储 安全 Java
Java语法掌握:打好编程基础的关键(二)
Java语法掌握:打好编程基础的关键
45 0
|
10天前
|
存储 Java
Java语法掌握:打好编程基础的关键(一)
Java语法掌握:打好编程基础的关键
10 0
Java语法掌握:打好编程基础的关键(一)
|
12天前
|
安全 Java
append在Java中是哪个类下的方法
append在Java中是哪个类下的方法
21 9
|
12天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
14 0
|
27天前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
25 0