Java之String类详解

String类在所有项目开发之中都会使用到!

1. 实例化方式

① 直接赋值:String str= "Hello world";

② 通过构造方法产生对象(传统法):String str = new String("Hello world");

public class ShiLiHua {
    public static void main(String[] args) {
        String str1 = "Hello world";
        String str2 = new String("Hello world!!!");
        System.out.println(str1);
        System.out.println(str2);
    }
}

在这里插入图片描述

***** 2. 字符串的相等比较

如果现在有两个int型变量,判断其相等可以使用 " == " 完成这是毋庸置疑的。但是如果要比较的是两个String类型呢?

public class XiangDengBiJiao {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        System.out.println(a==b);
        String str1 = "Hello";
        String str2 = new String("Hello");
        System.out.println(str1==str2);
    }
}

在这里插入图片描述
现在两个字符串内容相同,而使用 " == " 得到的结果却是不同的。

  • 内存图分析如下:
    在这里插入图片描述
    结论:" == " 操作符用于比较两个变量的值是否相等,对于基本类型而言比较的就是数值大小;而对于引用类型而言,比较的实际上是保存的地址是否相等而不会比较内容。

所以在字符串比较时,需要使用的是String类提供的equals()方法,这个方法区分大小写。要想不区分大小写可以使用equalsIngoreCase()方法。

public class XiangDengBiJiao {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = "hello";
        System.out.println(str1.equals(str2));
        System.out.println(str1.equals(str3));
        System.out.println(str1.equalsIgnoreCase(str3));
    }
}

在这里插入图片描述

面试题:请解释String类 " == " 与 equals 的区别。
① " == "进行的是数值比较,比较的是两个字符串对象的内存地址数值。
② " equals() "可以进行字符串内容的比较。

3. String类的匿名对象

所有字符串常量 (直接写出来的用" "括起来的字符串) 都是String类的匿名对象。

public class NiMingDuiXiang {
    public static void main(String[] args) {
        String str1 = new String("Hello");
        System.out.println("Hello".equals(str1));
        System.out.println(str1.equals("Hello"));
        //还有假设用户没有输入的情况下
        String str2 = null;
        System.out.println("Hello".equals(str2));
        System.out.println(str2.equals("Hello"));
    }
}

在这里插入图片描述
结论:在进行接收用户输入数据的时候一定要考虑到用户没有输入的问题,以上面代码为例,用户没有输入的时候,str2.equals("Hello")一定会出现空指针异常的错误 。而任何的字符串常量都是String类的匿名对象,该对象永远不会为null,所以"Hello".equals(str2)运行正常。因此在比较两个字符串是否等于特定字符串时,将字符串常量写在equals前面,通过字符串常量来比较

4. 两种实例化方式的区别

① 直接赋值

public class ShiLiHuaQuBie {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        System.out.println(str1==str2);
    }
}

在这里插入图片描述
可是我们刚刚已经说过 " == " 对于字符串来说是比较地址的,开辟新空间之后肯定用 " == " 结果是false的,这里的结果是true说明是没有开辟新空间的,这是为什么呢?

  • 内存图分析如下:
    在这里插入图片描述
    原因:在JVM内部会维护一个字符串常量池(对象数组),若采用直接赋值的方式进行String类的实例化操作,那么该对象会自动保存到对象池中。若下一次继续使用直接赋值的方式实例化String对象,先在对象池中寻找是否有指定对象,若有,直接引用,否则创建新空间,经新对象入池以供下次使用。也就是String类所谓的共享设计模式

② 构造赋值

String类本身毕竟是一个类,既然是类,那么类中一定存在构造方法。类对象使用构造方法实例化是标准做法。

public class ShiLiHuaQuBie {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        System.out.println(str1==str2);
    }
}

在这里插入图片描述
结论:说明构造方法产生的字符串常量并没有保存在对象池中。但是可以使用intern()方法手工入池,也是String类提供的方法。

public class ShiLiHuaQuBie {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        //手工入池
        String str3 = str2.intern();
        System.out.println(str1==str2);
        System.out.println(str1==str3);
    }
}

在这里插入图片描述
但是当使用构造方法实例化字符串时,实际上会开辟两次空间。因为程序执行顺序是从右向左执行的!!!以String str = new String("Hello")为例:

  • 内存图分析如下:
    在这里插入图片描述

面试题:请解释String类中两种对象实例化的区别。
① 直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
② 构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

5. 字符串常量不可变更

public class BuKeBianGeng {
    public static void main(String[] args) {
        String str = "Hello";
        str += "world";
        str += "!!!!";
        System.out.println(str);
    }
}

在这里插入图片描述

  • 内存图分析如下:
    在这里插入图片描述
    结论:堆中常量的值无法更改,但是栈中的指向可以更改。而且字符串不要改变太多次,慎用 “+” 字符串拼接操作,因为会产生大量垃圾空间。

原则
① 字符串使用就采用直接赋值。
② 字符串比较就使用equals()实现。
③ 字符串别改变太多。

6. 字符与字符串的相互转换

字符串就是一个字符数组,所以在String类里面支持字符数组转换为字符串以及字符串变为字符的操作方法。

① char[ ] => String

public String(char[] value) :将字符数组全部转为字符串

public String(char[] value, int offset, int len) :将字符数组的部分内容转为字符串

public class ZiFuYuZiFuChuan {
    public static void main(String[] args) {
    	//将字符串变为字符数组
        String str = "Hello world";
        char[] data = str.toCharArray();
        for(int i = 0; i < data.length; i++) {
            System.out.print(data[i]+"、");
        }
        //字符数组转为字符串
        System.out.println("\n"+new String(data));
        System.out.println(new String(data, 3, 7));
    }
}

在这里插入图片描述
② String => char

public char charAt(int index) :取得字符串指定索引的字符,从0开始

public class ZiFuYuZiFuChuan {
    public static void main(String[] args) {
        String str = "Hello";
        System.out.println(str.charAt(0));
        //如果现在超过了字符串长度,则会产生StringIndexOutOfBoundsException异常
        System.out.println(str.charAt(5));
    }
}

在这里插入图片描述
③ String => char[ ]

public char[] toCharArray() :将字符串转为字符数组

public class ZiFuYuZiFuChuan {
    public static void main(String[] args) {
        String str = "Hello world";
        char[] data = str.toCharArray();
        for(int i = 0; i < data.length; i++) {
            System.out.println(data[i]);
        }
    }
}

在这里插入图片描述

  • 现在有一个字符串判断其是否由数字所组成。
  • 因为现在不知道字符串的长度以及包含的内容,所以最好的做法是将字符串变为字符数组而后判断每一位字符是否是 " 0 " ~ " 9 "之间的内容,如果是则为数字。
public class ShuZi {
    public static void main(String[] args) {
        String str = "ab12cd";
        char[] data = str.toCharArray();
        int i;
        for(i = 0; i < data.length; i++) {
            if(data[i] >= '0' && data[i] <= '9') {
                System.out.println("有数字");
                break;
            }
            
        } 
        if(i > data.length) {
            System.out.println("没有数字");
        }  
    }
}

在这里插入图片描述

7. 字节与字符串的转换

字节常用于数据传输以及编码转换的处理之中,在String中提供有对字节的支持。

① byte[ ] => String

public String(byte[] value) :将字节数组全部转为字符串

public String(byte[] value, int offset, int len) :将字节数组的部分内容转为字符串

public class ZiJieYuZiFuChuan {
    public static void main(String[] args) {
    	//转换成字节数组
        String str = "Hello";
        byte[] data = str.getBytes();
        for(int i = 0; i < data.length; i++) {
            System.out.println(data[i]);
        }
        //转换成字符串
        System.out.println(new String(data));
        System.out.println(new String(data, 1, 3));
    }
}  

在这里插入图片描述
② String => byte[ ]

public byte[] getBytes() :将字符串转为字节数组

public byte[] getBytes(String charSet) :将字符串按照指定编码格式转为字节数组

Linux默认编码为UTF-8,在Windows默认编码是GBK。

public class ZiJieYuZiFuChuan {
    public static void main(String[] args) {
        String str = "Hello";
        byte[] data = str.getBytes();
        for(int i = 0; i < data.length; i++) {
            System.out.println(data[i]);
        }
    }
}

在这里插入图片描述

8. 字符串的比较

比较相等equalsequalsIngoreCase

比较大小public int compareTo(String anotherString) :比较两个字符串的大小关系。(负数:小于 0:相等 正数:大于)

public class BiJiaoDaXiao {
    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = "aBc";
        System.out.println(str1.compareTo(str2));
    }
}

在这里插入图片描述
结论:按照ASCII码比较,只要发现不相等的内容算出差值直接返回,不会继续向下查找。且比较汉字没什么意义。

9. 字符串查找

contains():判断一个字符串是否存在

indexOf():返回下标int型

lastIndexOf():(从指定位置)从后向前查找

startsWith():(从指定位置)判断是否以指定字符串开头

endsWith():判断是否以指定字符串结尾

public class ChaZhao {
    public static void main(String[] args) {
        String str = "$$helloworld!!";
        System.out.println(str.contains("hello"));
        System.out.println(str.indexOf("o"));
        //indexOf如果没有返回-1
        System.out.println(str.indexOf("o", 7));
        System.out.println(str.lastIndexOf("e"));
        System.out.println(str.lastIndexOf("e", 10));
        System.out.println(str.startsWith("$$"));
        System.out.println(str.startsWith("h", 2));
        System.out.println(str.endsWith("!!"));
    }
}

在这里插入图片描述

10. 字符串替换

Public String replaceAll(String regex, String replacement) :将字符串中所有指定内容替换为新内容

public String replaceFirst(String regex, String replacement) :将字符串首个字符替换为指定内容

public class TiHuan {
    public static void main(String[] args) {
        String str = "Hello world";
        System.out.println(str.replaceFirst("H", "h"));
        System.out.println(str.replaceAll("l", "_"));
    }
}

在这里插入图片描述

***** 11. 字符串拆分

public String[] split(String regex) :按照指定格式将字符串全部拆分

public String[] split(String regex, int limit) :将字符串部分拆分,数组长度为限定limit长度

注意返回值是字符串数组而不是字符串!!!

public class ChaiFen {
    public static void main(String[] args) {
        String str = "Hello world !!!";
        String[] result1 = str.split(" ");
        for(String s : result1) {
            System.out.println(s);
        }
        String[] result2 = str.split(" ", 2);
        for(String s : result2) {
            System.out.println(s);
        }
    }
}

在这里插入图片描述

  • 一般IP地址会用到拆分,IP地址里面的 " . " 有特殊含义,所以要转义。split方法中的参数时正则表达式," . " 原本需要一个 " \ " 来转义,但是正则表达式中 " \ " 也需要一个 " \ " 来转义,所以一共需要两个 " \ "。
public class ChaiFen {
    public static void main(String[] args) {
        String str = "192.168.1.1";
        String[] result = str.split("\\.");
        for(String s : result) {
            System.out.println(s);
        }
    }
}

在这里插入图片描述

12. 字符串截取

public String substring(int beginIndex) :从指定索引开始截取到字符串结尾

public String substring(int beginIndex, int endIndex) :从指定索引开始截取到指定索引结束

public class JieQu {
    public static void main(String[] args) {
        String str = "Hello world";
        System.out.println(str.substring(5));
        System.out.println(str.substring(5, 8));
    }
}

在这里插入图片描述
观察得出substring()方法截取字符串是左闭右开区间。

注意substring的写法,string不大写!!!

13. 其他方法

trim() :去掉字符串的左右两边空格,中间保留

toUpperCase() :将字符串转大写处理

toLowerCase() :将字符串转小写处理

length() :返回字符串长度,既可以作为属性也可以作为方法

isEmpty() :判断是否是空字符串,不包含null (即无法判断是null的情况)

null是空对象;""是空字符串对象,也是个对象。而isEmpty是要通过对象才能调用的,所以null没法判断。

public class QiTa {
    public static void main(String[] args) {
        String str = " hello world  ";
        System.out.println(str.trim());
        System.out.println(str.toUpperCase());
        System.out.println(str.toLowerCase());
        System.out.println(str.length());
    }
}

在这里插入图片描述

  • 如何只将首字母大写呢?String类并没有提供首字母大写操作,需要自己实现。
public class ShouZiMuDaXie {
    public static void main(String[] args) {
        String str = "hello world";
        System.out.println(firstUpperCase(str));
    }
    public static String firstUpperCase(String str) {
        return str.substring(0, 1).toUpperCase()+str.substring(1);
    }
}

在这里插入图片描述

  • 如何判断用户的输入就是个空字符串呢?
public class empty {
    public static void main(String[] args) {
        String str = null;
        //如果换成是 str.isEmpty() || str == null,一上来就是个空对象,
        //短路与,NullPointerException。
        if(str == null || str.isEmpty()) {
            System.out.println("空字符串");
        }
    }
}

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值