[Java]String类

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

目录

1、字符串构造

1.1、构造原理

2、String对象的比较

2.1、==

2.2、equals方法

2.3、compareTo方法

3、字符串查找

4、转化

4.1、数值和字符串转化

4.2、大小写转换

4.3、字符串转数组

4.4、格式化

4.5、去空格

5、字符串替代

6、字符串拆分

7、字符串截取

8、字符串的不可变性

9、字符串修改

9.1、StringBuilder和StringBuffer

9.2、字符串修改的效率


1、字符串构造

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

1.使用常量串构造

String  str = "hello"; // "hello" 字符串常量 ,没有\0 标记结尾
System.out.println(str); // 输出hello

^

2.直接new String对象

String str2 = new String(); // 调用String类不带参数的构造方法
System.out.println(str2); // 输出空白

.

String str3 = new String("pppp"); // 调用String类带参数的构造方法
System.out.println(str3); // 输出pppp

^

3.使用字符数组进行构造

char[] array ={'a','b','c'};
String str4 = new String(array);
System.out.println(str4); // 输出abc

.

char[] array ={'a','b','c'};
String str4 = new String(array,1,2);
System.out.println(str4); // 输出ab

1.1、构造原理

  String类的实现源码中,String类的成员变量如下

构造方法:

String s1 = new String("hello");

String s2 = new String("world");

String s3 = s1;

System.out.println(s1.length()); // 获取字符串长度---输出5

System.out.println(s1.isEmpty()); // 如果字符串长度为0,返回true,否则返回false

  注意区分字符串长度为0和字符串为null的情况:

String str4 = ""; // 表示字符串长度为0
System.out.println(str4.length()); // 输出0
System.out.println(str4.isEmpty()); // 输出true

^
String str5 = null; // 表示str5不指向任何对象

//System.out.println(str5.length()); // 空指针异常
System.out.println(str5.isEmpty()); // 空指针异常

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

// 打印"hello"字符串(String对象)的长度

System.out.println("hello".length());

2、String对象的比较

2.1、==

  ==比较是否引用同一个对象,比较的是引用中的地址

// 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象

String s1 = new String("abc");
String s2 = new String("abc");

String s3 = s1
System.out.println(s1 == s2); // 输出false

System.out.println(s1 == s3); // 输出true

^

// 对于基本类型变量,==比较两个变量中存储的值是否相同

int a = 10;

int b = 20;

int c = 10; 

System.out.println(a == b); // false

System.out.println(a == c); // true

2.2、equals方法

  String类重写了父类Object中equals方法,Object中equals默认按照 == 比较,String重写equals方法后,比较内容。  返回值是boolean类型的

String s1 = new String("hello");

String s2 = new String("hello");

String s3 = new String("Hello");

// equals比较:对String对象逐个字符进行比较

// 虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true

// s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出false System.out.println(s1.equals(s2)); // true

System.out.println(s1.equals(s3)); // false

2.3、compareTo方法

  String类实现了Comparable接口,重写了Comparable接口的compareTo方法

  具体比较方式:

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

String s1 = new String("abc");

String s2 = new String("ac");

String s3 = new String("abc");

String s4 = new String("abcdef");

 /**
 * s1 和 s2 进行比较
 * 如果s1 > s2 返回正数
* 如果s1 == s2 返回0
* 如果s1 < s2 返回负数

* 不能忽略大小写
 */
System.out.println(s1.compareTo(s2)); // 不同,输出字符差值-1 System.out.println(s1.compareTo(s3)); // 相同,输出 0

System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3

compareToIgnoreCase方法,可以忽略大小写比较

String s1 = new String("abc");
String s2 = new String("ac");
String s3 = new String("ABc");
String s4 = new String("abcdef");
System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1
System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0
System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同,输出长度差值 -3

3、字符串查找

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

1.char charAt(int index)

^

String s1 = "hello";
for (int i = 0; i < s1.length(); i++) {
        char ch = s1.
charAt(i);
        System.out.print(ch + " "); // 输出 h e l l o
}

2.int indexOf(int ch)

^

String s1 = "hello";

// 从头到后  查某个字符 第一次出现的下标
int index = s1.
indexOf('l');
System.out.println(index); // 输出2

.

3.int indexOf(int ch, int fromIndex)

^

 // 从fromIndex位置开始找ch第一次出现的位置
int index = s1.indexOf('l',3);
System.out.println(index); // 输出3

.

4.int indexOf(String str)

^

// 返回子串在主串中第一次出现的位置下标

String s1 = "ababcabcd";

int index = s1.indexOf("abc");
System.out.println(index); // 输出2

.

5.int indexOf(String str, int fromIndex)

^

// 从fromIndex位置开始找

String s1 = "ababcabcd";

int index = s1.indexOf("abc",3);
System.out.println(index); // 输出5

6.int lastIndexOf(int ch)

^

// 从后往前找,返回ch第一次出现的位置

String s1 = "ababcabcd";

int index = s1.lastIndexOf("abc");
System.out.println(index); // 输出5

.

7.int lastIndexOf(int ch, int fromIndex)

^

//从fromIndex位置开始找

String s1 = "ababcabcd";

int index = s1.lastIndexOf("abc",4);
System.out.println(index); // 输出2

8.int lastIndexOf(String str)

//从后往前找,返回str第一次出现的位置

9.int lastIndexOf(String str, int fromIndex)

//从fromIndex位置开始找,从后往前找str第一次出现的位置

4、转化

4.1、数值和字符串转化

valueOf

// 数字转字符串
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);

parseInt

// 字符串转数字
// Integer、Double等是Java中的包装类型
int data1 = Integer.
parseInt("1234");
double data2 = Double.
parseDouble("12.34");
System.out.println(data1);
System.out.println(data2);

4.2、大小写转换

toUpperCase
String s1 = "hello";

//转变为大写 不是在原来的基础上  转变  是转变成大写后是一个新的对象
String ret = s1.
toUpperCase();

System.out.println(s1); // hello
System.out.println(ret); // HELLO

^
toLowerCase
String s2 = "HEllo";

String ret2 = s2.toLowerCase();
System.out.println(s2); // HEllo
System.out.println(ret2); // hello

4.3、字符串转数组

toCharArray

String s1 = "hello";
char[] array = s1.
toCharArray();
System.out.println(Arrays.toString(array)); // [h,e,l,l,o]

^

// 数组转字符串

char[] array2 = {'a','b','c'};

String str2 = new String(array2);

System.out.println(str2); // abc

4.4、格式化

format
String s = String.format("%d-%d-%d", 2024, 12,19);
System.out.println(s); // 2024-12-19

4.5、去空格

trim

String str2 = "  fdsafsafdsa   fdsafsaf  ";
System.out.println(str2);

// 去掉字符串的左右两边的空格 中间的空格无法去掉
System.out.println(str2.
trim());

5、字符串替代

replace

可以看到replace有一个参数是CharSequence的

String实现了CharSequence接口,所以replace方法可以传入String类型的参数

^

String str = "ababcabcdabcde";
String ret = str.
replace("ab","00");

System.out.println(ret); // 0000c00cd00cde

ret = str.replace('a','8');
System.out.println(ret); // 8b8bc8bcd8bcde

ret = str.replaceFirst("ab","123");
System.out.println(ret); // 123abcabcdabcde
ret = str.
replaceAll("ab","123");
System.out.println(ret); // 123123c123cd123cde

6、字符串拆分

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

1.String[] split(String regex) -> 将字符串全部拆分

^

String str = "hello abc world";
String[] ret = str.
split(" "); // 以空格划分
for (int i = 0; i < ret.length; i++) {
    System.out.println(ret[i]);
}

2.String[] split(String regex, int limit) -> 将字符串以指定的格式,拆分为limit组

^

String str = "hello abc world";
String[] ret = str.
split(" ",2); // 以空格划分,拆成两组
for (int i = 0; i < ret.length; i++) {
    System.out.println(ret[i]);
}

  注意: 

1.字符 "|","*","+" 都得加上转义字符,前面加上 "\\" 

String str = "192.168.1.1";
String[] ret = str.split("\\."); //   \\ 表示 \,\. 表示 .
for (int i = 0; i < ret.length; i++) {
    System.out.println(ret[i]);
}

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

String str = "192\\168\\1\\1";
String[] ret = str.split("\\\\"); //   \\ 表示 \,\\\\表示\\
for (int i = 0; i < ret.length; i++) {
    System.out.println(ret[i]);
}

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

String str = "name=zhangsan&age=15";
String[] ret = str.split("=|&");
for (int i = 0; i < ret.length; i++) {
    System.out.println(ret[i]);
}

^

//也可以在 第一次分割的基础上 进行第二次分割
String[] ret = str.split("&");
for (int i = 0; i < ret.length; i++) {
    String x = ret[i];
    String[] ret2  = x.split("=");
    for (int j = 0; j < ret2.length; j++) {
        System.out.println(ret2[j]);
    }
}

7、字符串截取

1.String substring(int beginIndex) -> 从指定索引截取到结尾

String str = "ababc";

ret = str.substring(2);

System.out.println(ret); // abc

^

2.String substring(int beginIndex, int endIndex) -> 截取部分内容

String str = "ababc";
String ret = str.
substring(0,3); // [0,3)

System.out.println(ret); // aba

8、字符串的不可变性

  所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

String类在设计时就是不可改变的,String类实现描述中已经说明了(JDK1.8)

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

从图中可以看出

  • String类被final修饰,表明该类不能被继承
  • value被修饰被final修饰,表明value不能再引用其它字符数组,但是其引用空间中的内容可以修改

因此字符串不可变的原因与这两个 final 无关

决定字符串不可变的是value这个引用是私有的(private修饰),在其他类中无法拿到

9、字符串修改

  应尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下

public static void main(String[] args) {
    String s = "hello";
    s += " world";
    System.out.println(s); // 输出:hello world
}

// 这种方式不推荐使用,看似简单的操作,其实中间创建了好多临时对象,效率低

  这种写法与下述写法等价

public static void main(String[] args) {
    String str = "hello";
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(str);
    stringBuilder.append("abc");
    str = stringBuilder.toString();
    System.out.println(str);
}

// 可以看到过程中创建了StringBuilder对象和新的字符串对象

9.1、StringBuilder和StringBuffer

  由于String的不可更改特性,为了方便字符串的修改,Java中提供StringBuilder和StringBuffer类。这两个类的方法都一样,下面列举了一些常用方法

StringBuffer / StringBuilder 类的 append() 方法有三种语法形式,分别如下:

1. append(任意类型的参数):将参数以字符串的形式追加到 StringBuffer 对象的末尾。

2. append(任意类型的参数, 始索引, 束索引):将参数在指定索引之间的字符追加到StringBuffer 对象的末尾。

3.append(char[] chars):将参数以字符串的形式追加到StringBuffer对象的末尾。

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);

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

  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
  • StringBuilder变为String: 调用toString()方法

9.2、字符串修改的效率

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));

        // StringBuffer
        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));

        // StringBuilder
        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: 280
StringBuffer: 2
StringBuilder: 1

StringBuilder和StringBuffer的区别:

StringBuffer的方法比StringBuilder多了synchronized(保证线程安全)

StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

  总结:

  • 直接对String类型对象进行修改的效率最低,因为它在修改的过程中创建了很多对象
  • StringBuilder比StringBuffer的效率更高,因为同一时刻只有一个线程可以执行StringBuffer的方法,比StringBuilder多了上锁和开锁的步骤,耗费的更多时间

  String与StringBuffer、StringBuilder的区别:

  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改
  • String和StringBuffer、StringBuilder包含的方法不一样

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值