JAVA String类最全分析

一、介绍

StringSerializable实现它,String可以串行化,可以在网络上传输
ComparableString对象可以相互比较
CharSequence
Object

String

class Main{
    public static void main(String[] args) {
       //1.String 对象用于保存字符串,也就是一组字符序列
       //2."jack"字符串常量,双引号括起的字符串序列
        String name = "Jack";
        
       //3.字符串使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。
       //4.String是final类,不能被其他类继承
       //5.String 有属性 private final char value[];用于存放字符串内容
       //7.一定要注意:value 是一个final类型,不可以修改(地址不可修改,不可指向新的对象可以修改值)
​
    }
}

String类较常用构造器(其它看手册):

String s1 = new String(); 
​
String s2 = new String(String original);
​
String s3 = new String(char[]a);
​
String s4 = new String(char[]] a,int startlndex,int count)

二、创建刨析

易错分析

String中重写了Object中的equals方法,并重定义了它的功能,将其的地址比较改为了值比较,它改成了比较字符串是否相同

思考一:

//先在常量池里面创建了abc
//然后a指向它,同时b也指向它
//所以a,b的地址相同
​
String a = "abc";
String b = "abc";
System.out.printIn(a.equals(b));//T
System.out.println(a==b);

思考二

String a ="hsp"; //a 指向 常量池的“hsp'
String b =new String("hsp");//b 指向堆中对象
System.out.println(a.equals(b)); //T
System.out.println(a==b); //F
System.out.println(a==b.intern());//T //intern方法自己先查看API
System.out.println(b==b.intern());//F
​
知识点:
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用equals(object)方法确定),则返回池中的字符串。
否则,将此 String 对象添加到池中,并返回此 String 对象的引用
//解读:b.intern()方法最终返回的是常量池的地址(对象) 
​

思考三

//只创建一个对象
String a = "hello" + "world";
​
//创建了三个对象,如下图所示
//1.先创建一个 StringBuilder sb = stringBuilder()
//2.执行 sb.append("hello");
//3. sb.append("abc");
//4.string c= sb.tostring()
//最后其实是c指向堆中的对象(String)value[]->池中"helloabc"
​
String a = "hello";
String b = "word";
String c = a + b;

思考四

public class Test1 {
    String str = new String("hsp");
    final char[] ch = { 'j', 'a','v','a'};
        public void change(String str, char ch[]) {
            str ="java";
            ch[o] = 'h';
        }
public static void main(Stringl] args){
    Test1 ex = new Test1();
    //调用一个方法会产生一个新栈
    ex.change(ex.str, ex.ch);
    System.outprint(ex.str + "and ");
    System.out.println(ex.ch);
  }
}

三、String常用方法

public Main{
    public static void main(String[] args){
        
        //1.equals 区分大小写,判断内容是否相等
        
        //2.equalslgnoreCase 忽略大小写的判断内容是否相等
        
        //3.length() 获取字符的个数,字符串的长度
        
        //4. indexOf 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
        String s1 = "wer@eeyyy@g@";
        int index = s1.indexOf('@');
        System.out.println(index);//3
        //也可以是字符串
        System.out.println(s1.indexOf("er"));
​
        //5.lastIndexOf 获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
        String s1 = "wer@eeyyy@g@";
        int index = s1.lastIndexOf('@');
        System.out.println(index);//11
​
        //6.substring 截取指定范围的子串
        String name = "hello,张三";
        //下面name.substring(6)从索引6开始截取后面所有的内容
        System.out.println(name.substring(6));//截取后面的字符//张三
        //name.substring(0,5)表示从索引2开始截取,截取5个字符
        System.out.println(name.substring(2,5));//llo,张
   
        //7.trim 去前后空格
        
        //8.charAt 获取某索引处的字符,注意不能使用Str[index]这种方式
        
        //9.toUpperCase转换成大写
        String s = "heLLo";
        System.out.println(s.toUpperCase());
       
        //10.toLowerCase转换成小写
        System.out.println(s.toLowerCase());
      
        //11.concat拼接字符串
        String s1 = "宝玉”;
        s1 = s1.concat("林黛玉”).concat("薛宝钗”).concat("together");
        System.out.println(s1);
        
        //12.replace 替换字符串中的字符
        String s1 =“宝玉 and 薛宝钗 薛宝钗 薛宝钗”;
        //将s1中所有的 林黛玉 全部替换成 薛宝钗
        s1 = s1.replace("林黛玉”,“薛宝钗”);
        // s1.replace()方法执行后,返回的结果才是替换过的。
        // 注意对 s1没有任何影响
        System.out.println(s1);
        
        //13.split 分割字符串,
        //对于某些分割字符,我们需要 转义比如\等
        String poem ="锄禾曰当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        String split = poem.split(",");
        String poem = "E:\\aaa\\bbb";
        String[] split = poem.split("\\|");
        String[] split= poem.split("\\\\\");
        String[] split = poem.split("\\\\");
       
        for(int i=0;i<split.length;i++){
             System.out.printIn(split[i]);
        }
                                    
        //14.toCharArray 转换成字符数组
        String s= "happy";
        char[] chs = s.tocharArray();
        for(int i = 0;i < chs.length;i++){
            System.out.println(chs[i]);
        }
  
       //15.compareTo 比较两个字符串的大小,如果前者大,
       // 则返回正数,后者大,则返回负数,如果相等,返回0
       String a = "jchn";
       String b = "jack";
       System.out.println(a.compareTo(b));//返回值是'c' - 'a'= 2的值
                                   
       String a = "jac";// len = 3
       String b = "jack";// len = 4 
       System.out.println(a.compareTo(b));//返回值-1
                                   
       //16.format 格式字符串
          /*占位符有:
          *%s 字符串 %c 字符 %d 整型 %.2f 浮点型
          */
       String name =:"john";
       int age = 10;
       double score = 9.3 / 3;
       char gender ='男';
       //将所有的信息都拼接在一个字符串.
       String info = "我的姓名是"+ name +"年龄是"+ age +",成绩是"+ score +"性别是"+ gender + “希望大家!”;
       System.out.println(info);
​
       String info = String.format("我的姓名是%s年龄是%d,成绩是%.2f性别是%c.希望大家喜我!",name,age,score,gender);
    }
}                                  

四、StringBuffer类

1.基本介绍

StringBuffer代表可变的字符序列,可以对字符串内容进行增删

很多方法与但StringBuffer是可变长度

StringBuffer是一个容器

public class Main{
    public static void main(String[] args){
        //1.StringBuffer 的直接父类 是 AbstractStringBuilder
        //2.StringBuffer 实现了Serializable,即StringBuffer的对象可以串行化
        //3.在父类中 AbstractStringBuilder 有属性 char[] value,不是final,该value数组存放字符串内容,引出存放在堆中
        //4.StringBuffer 是一个 final 类,不能被继承
        //5.因为StringBuffer 字符内容是 存在 char[] value,所有在变化(增加/删除)
        //  不用每次都更换地址(即创建新对象),所以效率高于String
        StringBuffer stringBuffer = new StringBuffer("hello");
    }
}

1)String 保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 //private final char value[];

2)StringBuffer 保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用更新地址,效率较高

//char[ ] value; // 这个放在堆。

2.StringBuffer的构造器

StringBuffer()

构造一个其中不带字符的字符串缓冲区,其初始容量为16个字符。

StringBuffer(CharSequence seq)

public java.lang.StringBuilder(CharSequence seq)构造一个字符串缓冲区,它包含与指定的Charsequence 相同的字符。

StringBuffer(int capacity)//capacity[容量]

构造一个不带字符,但具有指定初始容量的字符串缓冲区。即对char 大小进行指定

StringBuffer(String str)

构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

3.StringBuffer类常见方法

1)增 append

2)删 delete(start,end)

3)改 replace(start,end,string) //将start----end 间的内容替换掉,不含end

4)查 indexOf //查找子串在字符串第1次出现的索引,如果找不到返回-1

5)插 insert(9,"张梅")

6)获取长度 length()

五、StringBuilder类

1.基本介绍

1)一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。

该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,

因为在大多数实现中,它比StringBuffer要快。

2)在StringBuilder上主要操作是 appand和insert方法,可重载这些方法,以接受任意类型的数据。

public class stringBuilder01 {
public static void main(string[] args){

//1.StringBuilder 继承 AbstractstringBuilder 类
//2.实现了 Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
//3.StringBuilder 是final类,不能被继承
//4.StringBuilder 对象字符序列仍然是存放在其父类 AbstractstringBuilder的 char[] value;
//因此,字符序列是堆中
//5.stringBuilder 的方法,没有做互斥的处理,没有synchronized 关键字,因此在单线程的情况下使用stringBuilder

StringBuilder stringBuilder = new stringBuilder();
    
   }
}
2.StringBuilder应用
String、StringBuffer 和StringBuilder的比较

1)StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样

2)String:不可变字符序列,效率低,但是复用率高

3)StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码

4)StringBuilder:可变字符序列、效率最高、线程不安全

5)String使用注意说明:

string s="a";//创建了一个字符串

s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s +"b"(也就是"ab")。

如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能 =>结论:如果我们对String 做大量修改,不要使用String。

效率:StringBuilder > StringBuffer > String

六、使用的原则,结论

1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder

2.如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder

3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer

4.如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等

StringBuilder 的方法使用和 StringBuffer 一样,不再说

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/798238.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android ImageDecoder把瘦高/扁平大图相当于fitCenter模式decode成目标小尺寸Bitmap,Kotlin

Android ImageDecoder把瘦高/扁平大图相当于fitCenter模式decode成目标小尺寸Bitmap&#xff0c;Kotlin val sz Size(MainActivity.SIZE, MainActivity.SIZE)val src ImageDecoder.createSource(mContext?.contentResolver!!, uri)val bitmap ImageDecoder.decodeBitmap(sr…

MySQL更新和删除(DML)

DML-修改数据 UPDATE 表名 SET 字段1 值1&#xff0c;字段2值2&#xff0c;....[WHERE 条件] 例如 1.这个就是把employee表中的这个name字段里面并且id字段为1的名字改为itheima update employee set nameitheima where id 1; 2.这个就是把employee这个表中的name字段和…

SpringMVC源码分析

文章目录 概要启动阶段请求阶段 概要 以下是调试mvc源码过程中用到的demo以及配置文件 webapp/WEB-INF/web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://…

熊海CMS漏洞练习平台的一次xss、sql注入、越权黑盒思路分析

简介 熊海CMS是由熊海开发的一款功能丰富的网站综合管理系统&#xff0c;广泛应用于个人博客、个人网站以及企业网站&#xff0c;本文章用于黑盒测试&#xff0c;如果需要「源码审计」后台回复【「CMS」】获取即可&#xff0c;精心准备了40多个cms源码漏洞平台&#xff0c;供宝…

记一次docker容器安装MySQL,navicat无法连接报错(10060错误)

今天在云服务器上使用docker部署mysql 8.0.11时&#xff0c;遇到了一个诡异的问题&#xff0c;在云服务器的docker容器内可以连接上mysql&#xff0c;然而在自己电脑上连接mysql时报错&#xff1a;Can‘t connect to MySQL server on localhost (10060) 下面是网上搜寻的几种可…

《SpringBoot 整合 Prometheus 采集自定义指标》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;如需交流&#xff…

C语言 ——— const关键字

目录 const修饰变量 const修饰指针变量 const放在指针类型之前 const放在指针类型之后 小结 const修饰变量 当 const 修饰 int类型 的 变量a 后&#xff0c;此时的 变量a 就具有长属性&#xff0c;就不能被赋值为其他的值 将 变量a的地址 存储到 指针变量pa 中&#xff…

计算机网络——常见问题汇总

1. introduction 1.1 Explain what a communication protocol is and why its important. A communication protocol is a set of rules and conventions(公约) that govern(统治) how data is transmitted and received between devices(设备), systems, or entities in a ne…

1、BOREDHACKERBLOG:社交网络

靶机&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 参考&#xff1a;Vulnhub靶机&#xff1a;BOREDHACKERBLOG: SOCIAL NETWORK_boredhackerblog系列-CSDN博客 需要使用virtualbox。 先去官网下载了最新版的vietualbox&#xff0c;以及把这…

使用 Unstructured.io 和 Elasticsearch 向量数据库搜索复杂文档

作者&#xff1a;来自 Elastic Amy Ghate, Rishikesh Radhakrishnan, Hemant Malik 使用非结构化和 Elasticsearch 向量数据库为 RAG 应用程序提取和搜索复杂的专有文档 在使信息可搜索之前解析文档是构建实际 RAG 应用程序的重要步骤。Unstructured.io 和 Elasticsearch 在此…

Admin.NET源码学习(2:安装并运行前端)

根据Admin.NET的GitHub主页介绍&#xff0c;前端运行步骤需要运行pnpm命令。百度pnpm的话&#xff0c;需要支持npm相关的命令支持。   根据参考文献4&#xff0c;安装Node.js后会提供npm命令支持&#xff08;npm是Node.js的软件包管理器&#xff0c;用于安装、发布和共享Jav…

FreeRTOS 入门 知识

什么是FreeRTOS FreeRTOS 是一个轻量级的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;由 Richard Barry 在 2003 年开发&#xff0c;并且由亚马逊的 FreeRTOS 项目&#xff08;一个由 Amazon Web Services (AWS) 支持的开源项目&#xff09;进一步推动和发展。FreeR…

顺序表算法 - 合并两个有序数组

88. 合并两个有序数组 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/merge-sorted-array/description/思路: void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int l1,l2,l3;l1 m-1;l2 n-1;l3 mn-1;//l1和l2大于…

DispatcherServlet懒加载带来的问题和思考

问题 DispatcherServlet的懒加载会导致在用户在进行第一次请求的时候会比正常慢很多&#xff0c;如果这个时候大量请求同时过来&#xff0c;那么阻塞和cpu的暴增就会显而易见。 背景 在回顾SpringMvc对servlet的增强的过程中&#xff0c;突然发现DispatcherServlet是懒加载的…

7.2 AQS原理

AQS 原理 概述 全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架。 特点&#xff1a; 用 state 属性来表示资源的状态&#xff08;分独占模式和共享模式&#xff09;&#xff0c;子类需要定义如何维护这个状态&#xff0c;控制如何获取锁和…

JAVA自定义注释

interface 声明 package test; public interface InProgress { } InProgress public void calculateInterest(float amount, float rate) { } 带成员 public interface TODO {String value(); } InProgress //只有成员变量名有value时&#xff0c;值有给value赋值时可以这…

redis源码分析之底层数据结构(一)-动态字符串sds

1.绪论 我们知道redis是由c语言实现的&#xff0c;c语言中是自带字符串的&#xff0c;但是为什么redis还要再实现自己的动态字符串呢&#xff0c;这种动态字符串的底层数据结构是怎样的呢?接下来我们带着这些问题来看一看redis中的动态字符串sds。 2.sds的组成 struct __at…

MySQL覆盖索引和索引跳跃扫描

最近在深入学习MySQL&#xff0c;在学习最左匹配原则的时候&#xff0c;遇到了一个有意思的事情。请听我细细道来。 我的MySQL版本为8.0.32 可以通过 show variables like version; 查看使用的版本。 准备工作&#xff1a; 先建表&#xff0c;SQL语句如下&#xff1a; c…

ARM学习(29)NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择

ARM学习&#xff08;28&#xff09;NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择 1、多种启动方式介绍 IMX1166 支持多组flexSPI 引脚启动&#xff0c;FlexSPI1以及FlexSPI2&#xff0c;通过boot cfg可以切换FlexSPI得实例。 每个实例又支持多组引脚&#xff0c;总共…