38、常用类之String类

news2025/1/10 17:07:28

1、基本介绍:

·String s5=new String(byte[] b);

(5)String实现了Serializable,说明String可以串行化,即可以网络传输

String实现了Comparable,说明String对象可以比较

(6)String和所有包装类都是final,不可被继承

String是一个final类,代表不可变的字符序列,字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的

(7)String有属性private final char value[]; 用于存放字符串内容(注意value是final类型,指向的地址不可修改(里面单个字符内容可以修改),因为基本类型的final是值不可修改,但char是引用类型,所以是地址不可修改)

package String_;
public class String01 {
    public static void main(String[] args) {
        String name="jack";
        name="tom";
        final char[] value={'a','b','c'};
        char[] v2={'t','o','m'};
        value[0]='H';//修改value里的内容
        //value=v2;//报错,因为value不能指向新的地址v2
        System.out.println(value);//输出:Hbc
    }
}

2、创建String对象的两种方式:

方式一:直接赋值String s="hspedu";

先从常量池查看是否有"hspedu"数据空间,如果有,直接指向;如果没有则重新创建,然后指向,s最终指向的是常量池的空间地址

方式二:调用构造器String s=new String("hspedu");

先在堆中创建空间,里面维护了value属性,指向常量池的"hspedu"空间,如果常量池没有"hspedu",重新创建,如果有,直接通过value指向,最终指向的是堆中的空间地址

String a="abc";
        String b="abc";
        System.out.println(a.equals(b));//T,比较内容
        //源码:public boolean equals(Object anObject) {
        //        if (this == anObject) {
        //            return true;
        //        }
        //        return (anObject instanceof String aString)
        //                && (!COMPACT_STRINGS || this.coder == aString.coder)
        //                && StringLatin1.equals(value, aString.value);
        //    }
        System.out.println(a==b);
        //T,比较地址,a在常量池没有找到"abc",所以创了一个"abc",
        // b在常量池里找到了a的"abc",所以指向了a的"abc",不用自己创了,
        // 所以它们指向的是同一个地址
String a="abc";
String b=new String("abc");
System.out.println(a==b);//F,a指向的是常量池里的对象,
// b指向的是堆中的对象(该对象又指向常量池里a的"abc")
System.out.println(a==b.intern());//T
System.out.println(b==b.intern());//T
//b.intern()指向的是常量池里a的对象,

补:b.intern()方法最终返回的是常量池的地址(对象)

当调用intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定),则返回池中的字符串,否则将此String对象添加到池中,并返回此String对象的引用

Person p1=new Person();
p1.name="hsp";
Person p2=new Person();
p2.name="hsp";
System.out.println(p1.name==p2.name);
//T,因为比较的是p.name的地址不是p的地址,
// 而p1.name和p2.name都指向常量池里的同一个地址

 

String s="abc";
s="hsp";
//创建了两个对象

String a="hello"+"abc";
//创建了一个对象,
//因为编译器会优化,判断创建的常量池对象,是否有引用指向,
//即等价于String a="helloabc"

(大家做题做着做疯魔了,像赌徒一样,好搞笑啊!)

 

String a="hello";
        String b="abc";
        String c=a+b;
        //底层分析:
        //1、先创建一个StringBuilder sb=StringBuilder();
        //2、执行sb.append("hello");
        //3、执行sb.append("abc");
        //4、String c=sb.toString;
        //sb是在堆中,并且append是在原来字符串的基础上追加的
        //最后其实是c指向堆中的对象(String) value[]——》池中"helloabc"

        String d="hello"+"abc";//d="helloabc"
        System.out.println(c==d);//false
        String e="helloabc"
        System.out.println(d==e);//true

        //常量相加,看的是池
        //变量相加,看的是堆

提示:尽量看源码学习

3、String类的常见方法:

String类是保存字符串常量的,每次更新都需要开辟空间,效率较低,因此java设计者还提供了StringBuilder和StringBu ffer来增强String的功能,并提高效率

package String_;
public class String01 {
    public static void main(String[] args) {
        String str1="hello";
        String str2="Hello";

        System.out.println(str1.equals(str2));//f, equals方法比较内容是否相同,区分大小写
        System.out.println(str1.equalsIgnoreCase(str2));//t, equalsIgnoreCase方法比较内容是否相同,不区分大小写

        System.out.println(str1.indexOf('e'));//输出:1,该字符第一次出现的地址
        System.out.println(str1.lastIndexOf('e'));//输出:1,该字符最后一次出现的地址

        System.out.println(str1.indexOf("el"));//输出:1,也可以是查找字符串第一个字母的地址
        System.out.println(str1.lastIndexOf("el"));//输出:1,查找字符串第一个字母最后一次出现的地址

        System.out.println(str1.substring(2));//输出:llo,截取索引2后面所有的字符
        System.out.println(str1.substring(0,2));//输出:he,截取索引为0到索引为2的所有字符
    }
}

 

package String_;
public class String01 {
    public static void main(String[] args) {
        String s="hello";

        System.out.println(s.toUpperCase());//HELLO
        System.out.println(s.toLowerCase());//hello

        s=s.concat(" cheer ").concat(" up ").concat("TV");
        System.out.println(s);//hello cheer  up TV
        System.out.println(s.replace("cheer","CHEER"));//hello CHEER  up TV
        //注意:s.replace()方法执行后对原来的s没有任何影响

        String poem="锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        String[] split=poem.split(",");//以逗号为标准对poem进行分割,返回一个数组
        for(int i=0;i<split.length;i++){
            System.out.println(split[i]);
        }
        //输出:
        //锄禾日当午
        //汗滴禾下土
        //谁知盘中餐
        //粒粒皆辛苦
        //注意:在对字符串进行分割时,如果有特殊字符,需要加入转义字符\
        //如要以"\\"为标准分割,那应该是String[] split=poem.split("\\\\");
        //因为一个\对应一个\,两个\\加起来就一共是\\\\个了

        char[] ch=s.toCharArray();//把字符串转换成字符数组
        for(int i=0;i<ch.length;i++){
            System.out.println(ch[i]);
        }

        String s1="hello";
        String s2="hi";
        System.out.println(s1.compareTo(s2));//输出:-4 //因为e-i=-4
        //前>后,返回正数;后>前,返回负数,前=后,返回0
        
        String s3="hello";
        String s4="h";
        System.out.println(s3.compareTo(s4));//输出:4  //因为s3.length-s4.length=4
        //如果前面部分都相同,如hello和he比较,则是则返回的是字符串长度的差
   }
}

package String_;
public class String01 {
    public static void main(String[] args) {
        String name="tom";
        int age=10;
        double score=98.8;
        char gender='男';
        String s="姓名:%s,年龄:%d,成绩:%.2f,性别:%c";//占位符,由后面的变量来替换
        System.out.println(String.format(s,name,age,score,gender));
        //输出:姓名:tom,年龄:10,成绩:98.80,性别:男
    }
}

(1)StringBuffer类

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

2)很多方法与String相同,但StringBuffer是可变长度的

3)StringBuffer是一个容器

4)StringBuffer的直接父类是AbstractStringBuilder

5)StringBuffer实现了Serializable, 说明StringBuffer可以串行化,即可以网络传输

6)父类AbstractStringBuilder有属性char[] value,不是final,该value数组存放字符串内容,引出的是存放在堆中的(不再是常量池)

7)StringBuffer是一个final类,不能被继承

StringBuffer stringBuffer=new StringBuffer();
StringBuffer stringBuffer1=new StringBuffer(100);
StringBuffer stringBuffer2=new StringBuffer("hello");

 

package String_;
public class String01 {
    public static void main(String[] args) {
        StringBuffer s=new StringBuffer("hello");
        s.append(" h");
        s.append("i").append(" 100").append(true).append(10.5);//追加
        System.out.println(s);//hello hi 100true10.5

        s.delete(2,3);//删除
        System.out.println(s);//helo hi 100true10.5

        s.replace(0,5,"cheer");//替换
        System.out.println(s);//cheerhi 100true10.5

        s.indexOf("c");//查找
        System.out.println(s);//输出:0

        s.insert(5," up! ");//增加
        System.out.println(s);//输出:cheer up! hi 100true10.5
    }
}

8)String 和StringBuffer的区别 

 

 4、练习题

 //我的代码

package String_;
import java.util.Scanner;
public class Homework01 {
    public static void main(String[] args) {
        System.out.println("请输入商品名称:");
        Scanner scanner1=new Scanner(System.in);
        System.out.println("请输入商品价格:");
        Scanner scanner=new Scanner(System.in);
        StringBuffer stringBuffer=new StringBuffer(String.valueOf(scanner));
        int j=stringBuffer.indexOf(".");
        for(int i=j;i>0;){
            stringBuffer.insert(i,",");
            i=i-3;
        }
        System.out.println("商品名称\t"+"商品价格");
        System.out.println(scanner1+"\t"+stringBuffer);

    }
}

//老师的代码

package String_;
import java.util.Scanner;
public class Homework01 {
    public static void main(String[] args) {
        String price="1234567.59";
        StringBuffer sb=new StringBuffer(price);
        for(int i=sb.lastIndexOf(".")-3;i>0;i-=3){
            sb=sb.insert(i,",");
        }
        System.out.println(sb);//1,234,567.59
    }
}

(2)StringBuilder类

1)是一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全),该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用时,如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快

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

 3)StringBuilder和StringBuffer均代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样

4)StringBuilder是final

5)继承了AbstractStringBuilder,属性char[] value,内容存到value,因此字符序列是在堆中

6)实现了Serializable接口,StringBuilder对象可以串行化,即可以网络传输,可以保存到文件。序列化(所谓序列化即可以保存类型和数据本身)

7)StringBuilder的方法,没有做互斥处理,即没有synchronized关键字,因此在单线程的情况下使用

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript基础(13)_原型、原型对象

上一章构造函数确实简化了多个对象创建的麻烦问题&#xff0c;但是&#xff1a;构造函数每创建一个实例&#xff0c;构造函数就会执行一次&#xff0c;将属性和方法添加到该对象&#xff0c;每个对象实例化后地址互不相同&#xff0c;即使它们的方法所实现的逻辑和功能一样&…

pytorch初学笔记(八):神经网络之卷积操作

目录 一、卷积操作 二、二维卷积操作 2.1 torch.nn.functional 2.2 conv2d方法介绍 2.2.1 使用该方法需要引入的参数 2.2.2 常用参数 2.2.3 关于对input和weight的shape详解 三、代码实战 3.1 练习要求 3.2 tensor的reshape操作 3.3 不同stride的对比 3.4 不同pad…

Docker面试

1. Docker和虚拟机的区别&#xff1f; 虚拟机Virtual Machine与容器化技术&#xff08;代表Docker&#xff09;都是虚拟化技术&#xff0c;两者的区别在于虚拟化的程度不同。 隔离性 由于vm对操作系统也进行了虚拟化&#xff0c;隔离的更加彻底。而Docker共享宿主机的操作系统…

数字化转型总体需求

基于“两型三化九力”对企业数字化的要求&#xff0c;以建设产品全生命周期管理平台为手段和途径&#xff0c;打通设计、工艺、制造及交付服务的全生命周期的数字线&#xff0c;实现数字化设计、数字化仿真、数字化制造、数字化服务及数字化管理&#xff0c;未来以此为基础实现…

【计算机毕业设计】11.毕业生信息管理系统+vue

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 毕业生信息招聘平台&#xff0c;主要的模块包括查看管理员&#xff1b;首页、个…

zk常用命令ls、ls2、get、stat,参数意思(重补早期学习记录)

前言:补学习记录,几年前写一半丢草稿箱,突然看到,有强迫症所以补完 1.连接zk客户端(进入zk后台) ./zkCli.sh 连接成功 使用help查看有哪些命令可以使用 试试ls和ls2的区别 ls显示指定路径下的目录 ls2不仅可以 显示指定路径下的目录,还可以显示该节点的相关状态信息…

OpenGL 单色

目录 一.OpenGL 单色图 1.IOS Object-C 版本1.Windows OpenGL ES 版本2.Windows OpenGL 版本 二.OpenGL 单色 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >…

非关系型数据库MongoDB是什么/SpringBoot如何使用或整合MongoDB

写在前面&#xff1a; 继续记录自己的SpringBoot学习之旅&#xff0c;这次是SpringBoot应用相关知识学习记录。若看不懂则建议先看前几篇博客&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 3.4.3.3 Mongodb 3.4.3.3.1 介绍 MongoDB是一个开…

【Tomcat专题】Tomcat如何打破双亲委派机制?

文章目录类加载器双亲委派机制双亲委派的好处Tomcat的类加载器loadClass总体加载步骤&#xff1a;类加载器 三种JDK内部的类加载器 启动类加载器&#xff08;BootStrap ClassLoader&#xff09; 负责加载JRE\lib下的rt.jar、resources.jar、charsets.jar包中的class。 扩展…

一文带你搞懂sklearn.metrics混淆矩阵

一般的二分类任务需要的评价指标有4个 accuracyprecisionrecallf1-score 四个指标的计算公式如下 计算这些指标要涉及到下面这四个概念&#xff0c;而它们又构成了混淆矩阵 TP (True Positive)FP (False Positive)TN (True Negative)FN (False Negative) 混淆矩阵实际值01预测…

周杰伦腾格尔晚上八点同时开线上演唱会,究竟是巧合还是刻意安排

从日历上面看&#xff0c;2022年11月19日&#xff0c;是一个再平凡不过的日子&#xff0c;不过有了周杰伦和腾格尔的加持&#xff0c;这个平凡的日子也变得不平凡了。根据腾格尔老师本人透露&#xff0c;他准备在11月19日&#xff0c;在某音平台开启线上演唱会&#xff0c;为歌…

智慧实验室解决方案-最新全套文件

智慧实验室解决方案-最新全套文件一、建设背景二、建设架构智慧实验室建设核心目标三、建设方案四、获取 - 智慧实验室全套最新解决方案合集一、建设背景 当前高校和中小学的智慧校园建设正如火如荼地进行中&#xff0c;智慧实验室建设属于“智慧校园”建设的重要组成部分之一…

ctf_BUUCTF_web(1)

文章目录BUUCTF_webSQL注入1. [极客大挑战 2019]EasySQL2. [SUCTF 2019]EasySQL3.[强网杯 2019]随便注4.[极客大挑战 2019]BabySQL5.[BJDCTF2020]Easy MD56.[极客大挑战 2019]HardSQL7.[GXYCTF2019]BabySQli8.[GYCTF2020]Blacklist9.[CISCN2019 华北赛区 Day2 Web1]Hack World1…

面试:HTTP 的长连接和短连接

https://www.cloudflare.com/zh-cn/learning/ddos/syn-flood-ddos-attack/ 一文搞懂 HTTP 的长连接和短连接_文晓武的博客-CSDN博客 1、HTTP 协议与 TCP/IP 协议的关系 HTTP 的长连接和短连接本质上是 TCP 长连接和短连接。HTTP 属于应用层协议&#xff0c;在传输层使用 TCP…

区块链交易明细中各字段的含义

Transaction Hash&#xff1a;标识本次交易的 hashStatus&#xff1a;交易状态Block&#xff1a;7768188 表示本次块高&#xff0c;217034 表示在 7768188 后面又新挖的区块数量&#xff0c;该数值会随着新区块增加而不断增长Timestamp&#xff1a;交易成功的时间戳From&#x…

直流无刷电机(BLDC)转速闭环调速系统及Matlab/Simulink仿真分析

文章目录前言一、转速闭环直流调速系统二、Matlab/Simulink仿真2.1.仿真电路分析2.2.仿真结果分析总结前言 变压调速是直流调速系统的主要调速方法&#xff0c;因此系统的硬件至少包含&#xff1a;可调直流电源和直流电机两部分。可调直流电源多采用直流PWM变换器&#xff0c;…

v-for的用法及key值原理

v-for的用途&#xff1a; &#xff08;1&#xff09;关键字&#xff1a; v-for遍历的时候&#xff0c;关键字有两个&#xff1a;in、of&#xff1a;两个关键字没有区别&#xff0c;用哪一个都行&#xff1b; &#xff08;2&#xff09;支持对象、数组、数字遍历&#xff1a…

java线程生命周期

如图 java线程的生命周期主要分为 新建: :新建这一刻 他会创建出一个线程对象 这个就是我们通过new线程类 这部操作实现的 当我们通过new出来的线程对象 执行 start方法之后 他就会进入第二个生命周期 就绪: 在这个过程中 他有执行资格 就是他是可以执行线程的程序的 但这个阶…

zk中session的基本原理、create、set、delete命令的使用(重补早期学习记录)

前言:补学习记录,几年前写一半丢草稿箱,突然看到,有强迫症所以补完 一、session基本原理 二、创建节点 create [-s] | [-e] 路径 数据 权限 还是一样的连接zk客户端 ./zkCli.sh 使用help查看命令 我们创建一个父节点,并存入数据 使用get来或者它的数据和状态信息 状态参…

【LeetCode】Day187-分割回文串

题目 131. 分割回文串【中等】 题解 如何判断字符串是回文串&#xff1f; 使用动态规划&#xff1a;f[i][j]代表s[i…j]是否是回文串&#xff0c;则有状态转移方程如下&#xff0c; 有了f[i][j]&#xff0c;如何分割回文串&#xff1f; 利用回溯搜索&#xff0c;当s[0…i-1…