文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java【String类】的详解

2023-08-31 12:24

关注

目录

🐲 1.了解String类

🐲 2.String类常用方法

🦄 2.1 字符串构造

🦄 2.2 字符串查找

🦄 2.3 字符串截取

🦄 2.4 字符串替换

🦄 2.5 字符串拆分

🦄 2.6 字符串修改

🦄 2.7 相互转化

🦄 2.8 String对象比较

🦄 2.9 去除字符串左右空格

🐲 3. 字符串常量池

🦄 3.1 理解池的概率

🦄 3.2 字符串常量池

🐲 4. 字符串不可变性

🐲 5. StringBuilder和StringBuffer

🐲6. 就本篇所提到的方法进行大致总结


🤠 String类 (字符串类型)

在C中是没有字符串类型的,要定义一个字符串,只能通过指针去指向引用它

而在Java中,创造了一个新的类型,那就是String类

通过String可以直接定义一个变量,这个变量可以直接就是字符串

String str = "hello";

🤠 在jdk1.8帮助手册中,可以查看到

🤠 String也有很多构造方法,比如这些 


🦄 2.1 字符串构造

通过查看jdk1.8帮助手册,发现String提供的构造方法非常多

🤠下面就看常用的三种吧

    public static void main(String[] args) {        //1.直接定义一个字符串        String str = "hello";        System.out.println(str);        //2.通过new String对象        String str2 = new String("xawl");        System.out.println(str2);        //3.通过字符数组进行构造        char[] chars = {'a','b','c'};        String str3 = new String(chars);        System.out.println(str3);    }

根据在内存中的存储方式,理解一下上面三种构造方法是如何存储的 

⚜️先查看一下String源码发现

⚜️ 现在Debug先调试一波,看一下是怎么存储的

 

🤠 如果要求字符串长度,应该怎么做

        //字符串求长度,length()是一个方法        System.out.println(str.length());        //数组求长度        int[] array = {1,2,3};        System.out.println(array.length);

🤠也可以直接给字符串.length() 求长度 

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

🦄 2.2 字符串查找

🤠(1)char charAt(int index),输入位置index,找单个字符

    public static void main(String[] args) {        String s1 = "hello";        char ch = s1.charAt(1);        System.out.println(ch);//e    }

⚜️如果说输入一个不合法的位置,去查找这个字符,就会 

 ⚜️如果说需要拿到这些字符去运算呢

    public static void main(String[] args) {        String s1 = "hello";        for (int i = 0; i < s1.length(); i++) {            char ch = s1.charAt(i);            System.out.println(ch);        }    }

🤠(2)int indexOf(int ch)   ,返回ch字符第一次出现的位置下标,没有就返回-1

        int index = s1.indexOf('l');        System.out.println(index);//2

🤠 (3)  int indexOf(int ch, int fromIndex),从fromIndex位置开始找ch字符第一次出现的位置,没有就返回-1 

        int index = s1.indexOf('l',4);        System.out.println(index);//-1        int index1 = s1.indexOf('l',3);        System.out.println(index1);//3

🤠(4)int indexOf(String str),找Str字符串第一次出现的位置,返回其字符串首字母下标,没有返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxh";        int index2 = s2.indexOf("xawl");        System.out.println(index2);//5    }

🤠(5)int indexOf(String str,int formIndex),从formIndex开始,找Str字符串第一次出现的位置,返回其字符串首字母下标,没有返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxhxawllxh";        int index2 = s2.indexOf("xawl",6);        System.out.println(index2);//12    }

🤠(6)int lastIndexOf(int ch),从后往前找字符ch,返回从后往前第一次出现ch字符的下标,没有找到返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxhxawllxh";        int index3 = s2.lastIndexOf('a');        System.out.println(index3);//13    }

🤠(7)int lastIndexOf(int ch,int fromIndex),从fromIndex开始,从后往前找字符ch,返回从后往前第一次出现ch字符的下标,没有找到返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxhxawllxh";        int index3 = s2.lastIndexOf('a',7);        System.out.println(index3);//6    }

🤠(8)int laseIndexOf(String str),从后往前找,返回字符串str第一次出现位置的首字母下标,没有找到返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxhxawllxh";        int index4 = s2.lastIndexOf("xawl");        System.out.println(index4);//12    }

🤠(9)int laseIndexOf(String str,int formIndex),从fromIndex开始,从后往前找,返回字符串str第一次出现位置的首字母下标,没有找到返回-1

    public static void main(String[] args) {        String s2 = "helloxawllxhxawllxh";        int index4 = s2.lastIndexOf("xawl",9);        System.out.println(index4);//5    }

总结一下,

输入下标,找单个字符,用charAt方法;

找字符或字符串,需要返回下标

如果是从前往后找,用indexOf方法;

如果是从后往前找,用lastIndexOf方法;

🦄 2.3 字符串截取

🤠从字符串中截取后面字符串的内容,通过substring,

    public static void main(String[] args) {        String str = "adsasdasdasdasd";        String ret = str.substring(4);        System.out.println(ret);//sdasdasdasd    }

🤠如果是要截取指定部分内容,可以指定其左右下标范围,但是注意范围是不包括右的[左,右) 

    public static void main(String[] args) {        String str = "adsasdasdasdasd";        String ret = str.substring(4,7);//截取[4,7)里面的字符        System.out.println(ret);//sda    }

总结一下,

截取字符串,可以使用subString 


🦄 2.4 字符串替换

原来的字符串不变,创建一个新的字符串,替换新字符串中某个字符

🤠  使用replace将字符串中字符进行替换

    public static void main(String[] args) {        String str1 = "xawlxawlxawlxawl";        String ret = str1.replace('a','B');        System.out.println(ret);//xBwlxBwlxBwlxBwl        System.out.println(str1);//xawlxawlxawlxawl    }

🤠使用replace或replaceAll将字符串中字符串进行替换

    public static void main(String[] args) {        String str1 = "xawlxawlxawlxawl";        String ret = str1.replace("xa","B");        String ret1 = str1.replaceAll("xa","B");        System.out.println(ret);//BwlBwlBwlBwl        System.out.println(ret1);//BwlBwlBwlBwl        System.out.println(str1);//xawlxawlxawlxawl    }

 🤠  使用replaceFrist将字符串中字符进行替换

    public static void main(String[] args) {        String str1 = "xawlxawlxawlxawl";        String ret1 = str1.replaceFirst("xa","B");        System.out.println(ret1);//Bwlxawlxawlxawl    }

总结一下,

(1)替换字符串中的字符 ,用replace

(2)替换字符串中的字符串 ,用replace或replaceAll

(3)替换字符串中的首个字符串,用replaceFirst


🦄 2.5 字符串拆分

🤠可以将一个完整的字符串按照指定的分隔符,分隔为若干个字符串,用spllit

    public static void main(String[] args) {        String str1 = "Hello this is xawl rjgc professional";        String[] ret = str1.split(" ");        for (String s : ret) {            System.out.println(s);        }    }


🤠将字符串以指定的格式,拆分为limit组  

    public static void main(String[] args) {        String str1 = "Hello this is xawl rjgc professional";        String[] ret = str1.split(" ",3);        for (String s : ret) {            System.out.println(s);        }    }

🤠这里还要注意,有些特殊字符(| + * . ,)作为分割符可能无法正确切分, 需要加上转义. 

比如," . "点号,如果要识别IP地址中的点号,直接通过split进行拆分是识别不出点号作为分割符的,需要加上转义字符,也就是  \\.

        String str2 = "192.188.12.1";        String[] ret1 = str2.split("\\.");        for (String s1: ret1) {            System.out.println(s1);        }

  🤠 遇到这些特殊字符,需要加上转义也就是\\,

如果是遇到了\\这个特殊字符,那就要写成\\\\

        String str2 = "192\\188\\12\\1";        String[] ret1 = str2.split("\\\\");        for (String s1: ret1) {            System.out.println(s1);        }

 🤠 如果是一个字符串中有多个分隔符,那么用 | 作为连字符

        String str3 = "avasda asda&sad";        String[] ret2 = str3.split(" |&");        for (String s2: ret2) {            System.out.println(s2);        }

🤠 如果是通过多个分隔符来进行多次分割,可以怎么做

     可以通过多次for-each循环来split分隔字符串

        String str4 = "asda=sdas&dasd=asd";        String[] ret3 = str4.split("=");        for (String s : ret3) {            String[] s1 = s.split("&");            for (String x : s1) {                System.out.println(x);            }        }

 总结一下,

如果要字符串进行拆分,可以用split

但是要注意如果是特殊分隔符,那就需要转义

如果通过多个分隔符对字符串进行分割可以多次for-each循环分割


🦄 2.6 字符串修改

        long start = System.currentTimeMillis();        String s = "" ;        for (int i = 0; i < 100000; ++i) {            s += i;        }        long end = System.currentTimeMillis();        System.out.println(end - start);

🤠如果是这样的对字符串修改,那就会导致每次修改都会创建新对象,如果这样10W次,         那效率是非常低下的

   所以我们应该避免直接对String类型对象进行修改。

    如果非要修改那可以使用StringBuffer和StringBuilder进行修改


🦄 2.7 相互转化

🤠(1)数字和字符串转化valueOf

🤠数字转字符串,用String.valueOf(),各种类型的数字都可以传

    public static void main(String[] args) {        String str = String.valueOf(1234);        String str1 = String.valueOf(12.34);        System.out.println(str);        System.out.println(str1);    }

🤠也可以将一个对象转为字符串

定义一个学生类 

class Student{    private int age ;    public Student(int age) {        this.age = age;    }    @Override    public String toString() {        return "Student{" +                "age=" + age +                '}';    }}

直接在valueof里面new Student就可以了 

public class Test01 {    public static void main(String[] args) {        String str2 = String.valueOf(new Student(20));        System.out.println(str2);    }}

 🤠数字字符串转数字,用Integer.valueOf()(或Integer.valueOf())

⚜️ 直接传数字字符串,就可以转数字了

    public static void main(String[] args) {        int a = Integer.valueOf("1234");        System.out.println(a);//1234            }

 ⚜️ 也可以传数字字符串,转成所需进制的数字

    public static void main(String[] args) {        int a = Integer.valueOf("1234",8);        System.out.println(a);//668    }

🤠(2)字母大小写转化toUpperCase()和toLowercase()

⚜️小写字母转大写字母用toUpperCase() ,只转化字符串中的字母,汉字不影响

 

    public static void main(String[] args) {        String str3 = "abcdef阿凡达";        String ret = str3.toUpperCase();        System.out.println(ret);//ABCDEF阿凡达    }

 ⚜️大写字母转小写字母用toLowerCase(),

    public static void main(String[] args) {        String str4 = "ABCDEF阿凡达";        String ret1 = str4.toLowerCase();        System.out.println(ret1);//abcdef阿凡达    }

🤠这里要注意,大小写转化,不是在原来的字符串中修改,

     而是产生一个新的字符串对象进行修改 

    public static void main(String[] args) {        String str4 = "ABCDEF阿凡达";        String ret1 = str4.toLowerCase();        System.out.println(ret1);//abcdef阿凡达        System.out.println(str4);//ABCDEF阿凡达    }

🤠(3)字符串和数组转化toCharArray()和new String()

⚜️字符串转数组用toCharArray()

        String str5 = "hello";        char[] chars = str5.toCharArray();        for (char x : chars) {            System.out.println(x);        }

⚜️数组转字符串直接new String

        char[] chars1 = {'a','b','c'};        String str6 = new String(chars1);        System.out.println(str6);//abc

🤠(4)格式化输出用String.format()

        String str7 = String.format("%d-%d-%d",2022,5,28);        System.out.println(str7);//2022-5-28

 总结一下,

(1)数字和字符串转化用 String.valueof和Integer.parselnt(或Integer.valueof)

(2)大小写转化用toUpperCase和toLowerCase

(3)字符串和数组转化用toCharArray和new String

(4)格式化输出用format


🦄 2.8 String对象比较

⚜️ 先new上三个字符串

        String s1 = new String("hello");        String s2 = new String("hello");        String s3 = new String("world");

⚜️ 如果直接比较

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

都会是false,因为new String 是在堆上去创建不同的空间,通过s1,s2,s3,分别去指向他们 

(1)也就是对于引用类型,==比较的是地址;

         而对于基本类型变量,==比较的是存储的值 ;


🤠 如果说使用equals比较相不相同呢

(2)String类重写了父类Object中equals方法,         Object中equals默认按照==比较,        String重写equals方法后,就会发生动态绑定

 ⚜️ 下面使用重写后的equals进行比较

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

 🤠 如果说使用compareTo比较大小关系呢

(3)String也重写了compareTo ,可以进行大小关系的比较

        System.out.println(s1.compareTo(s1));//0        System.out.println(s2.compareTo(s3));//-15

  🤠 如果说使用compareToIgnoreCase比较大小关系呢

  🤠 或者使用equalseToIgnoreCase比较大小关系呢

(4)使用compareToIgnoreCase进行比较,可以忽略字母大小写,来进行比较大小关系

         使用equalsToIgnoreCase进行比较,可以忽略字母大小写,来进行比较是否相等

    public static void main(String[] args) {        String s1 = new String("hello");        String s4 = new String("HELLO");        //直接比较大小关系        System.out.println(s1.compareTo(s4));//32        //忽略大小写进行比较        System.out.println(s1.compareToIgnoreCase(s4));//0        //直击比较是否相等        System.out.println(s1.equals(s4));//false        //忽略大小写比较是否相等        System.out.println(s1.equalsIgnoreCase(s4));//true    }

🦄 2.9 去除字符串左右空格

🤠 去掉字符串中的左右空格,保留中间空格,用trim
    public static void main(String[] args) {        String str = "   asdasdasdas    ";        System.out.println(str.trim());//asdasdasdas    }

🦄 3.1 理解池的概率

在java中,字面类型的常量经常频繁使用,而为了使程序的运行速度更快,更节省内存,java给8种基本数据类型和String类都提供了常量池

在java中,为了提高效率,还有很多的“池”,比如内存池,线程池等,

为了节省存储空间和提高程序的运行效率,java中还有这些池:

Class文件常量池,运行时常量池,字符串常量池,

这里主要介绍字符串常量池


🦄 3.2 字符串常量池

字符串常量池在JVM中是StringTable类,实际上是一个固定大小的HashTable

不同JDK版本下字符串常量池位置大小是不同的

JDK版本字符串常量池位置大小设置
Java6方法区固定大小:1009
Java7默认大小:60013,可自行设置
Java8最小:1009,可以自行设置

🤠 1. 通过字符串常量进行赋值

因为指向的常量池是同一个,所以s1等于s2,返回true 

    public static void main(String[] args) {            String s1 = "hello";            String s2 = "hello";            System.out.println(s1 == s2); // true    }

🤠  2.通过new创建String类对象

 ⚜️ s1和s3的地址是不相同的,所以比较就是false

    public static void main(String[] args) {            String s1 = "hello";            String s2 = "hello";            String s3 = new String("hello");            System.out.println(s1 == s2); // true            System.out.println(s1 == s3); // false    }

⚜️ 打个断点调试后,发现这三个引用的数组也是一样的 

🤠 3. intern方法 

⚜️ 没使用intern方法前

    public static void main(String[] args) {            char[] ch = new char[]{'a', 'b', 'c'};            String s1 = new String(ch);             String s2 = "abc";             System.out.println(s1 == s2);//false    }

⚜️ 使用intern方法后

    public static void main(String[] args) {            char[] ch = new char[]{'a', 'b', 'c'};            String s1 = new String(ch);             s1.intern();            String s2 = "abc";            System.out.println(s1 == s2);    }

 

🤠 所以intern的作用是:检查s1所指向的对象在常量池中是否存在,

     如果不存在就把当前对象入池;存在就返回常量池中的对象



⚜️ 这里先看一下String,

String类是一个不可变类,即创建String对象后,该对象中的字符串是不可改变的,直到这个对象被销毁。 

⚜️ StringBuffer与StringBuilder 

StringBuffer与StringBuilder都继承自AbstractStringBuilder类,AbstractStringBuilder中也是使用字符数组保存字符串,是可变类。

并且都提供了一系列插入、追加、改变字符串里的字符序列的方法,它们的用法基本相同

 ⚜️ 下面可以看一下二者的用法

StringBuilder.append:添加任意类型数据的字符串形式,并返回当前对象自身

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

StringBuilder.reverse 逆置字符串

    public static void main(String[] args) {        StringBuilder stringBuilder= new StringBuilder();        stringBuilder.append("hello");        stringBuilder.append("world");        stringBuilder.reverse();        System.out.println(stringBuilder);//dlrowolleh    }

StringBuffer.apppend

    public static void main(String[] args) {        StringBuffer stringBuffer= new StringBuffer();        stringBuffer.append("hello");        stringBuffer.append("world");                System.out.println(stringBuffer);//helloworld    }

 StringBuffer.reverse 逆置字符串

    public static void main(String[] args) {        StringBuffer stringBuffer= new StringBuffer();        stringBuffer.append("hello");        stringBuffer.append("world");        stringBuffer.reverse();        System.out.println(stringBuffer);//dlrowolleh    }

StringBuilder和StringBuffer二者的区别

打开二者append的原码,观察发现

 二者相比较,StringBuffer更安全,但并不是说StringBuffer比StringBuilder要更好,

因为StringBuffer的安全是建立在相对来说降低效率和耗费资源的基础之上的。

二者就方法来说,基本都是一样的。

StringBuffer和StringBuilder和String的区别

(1)String内容不可以修改,而StringBuffer与StringBuilder,提供了一系列插入、追                 加、 改变字符串里的字符序列的方法,并且修改不产生新的对象,而是在原对象的基            础上修改

(2)就三者效率进行比较

         StringBuilder > StringBuffer > String

(3)从安全性和操作数据量来比较

         如果要操作的数量比较小,应优先使用String类;

         如果是在单线程下操作大量数据,应优先使用StringBuilder类;

         如果是在多线程下操作大量数据,应优先使用StringBuffer类。

(4)StringBuffer使用了缓存区,StringBuilder没有使用缓存区,所以没有修改数据的情             况下,多次调用StringBuffer的toString方法获取的字符串是共享底层的字符数组的。

         而StringBuilder不是共享底层数组的,每次都生成了新的字符数组


方法作用
charAt()输入下标,找单个字符
indexOf()从前往后找,找字符或字符串,需要返回下标
lastIndexOf()从后往前找,找字符或字符串,需要返回下标
split()对字符串进行拆分,注意特殊字符,需要转义
repalce()替换字符串中的字符
replace()/replaceAll()替换字符串中的字符串
replaceFrist()替换字符串中的首个字符串
subString()截取字符串
String.valueof()数字转字符串
Integer.parselnt() / Integer.valueof()字符串转数字
toUpperCase()字母小写转大写
toLowerCase()字母大写转小写
toCharArray()字符串转数组
new String()数组转字符串
format()格式化输出
String.equals()比较字符串相不相等,返回boolean类型
String.compareTo()比较字符串大小关系,返回int 类型
equlsTolgnoreCase()忽略字母大小写,比较是否相等
trim()去掉字符串中,首尾部空格,保留中间空格

来源地址:https://blog.csdn.net/m0_58761900/article/details/125014074

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯