补坑:Java的字符串String类(1)

常用方法

字符串构造

来看看源码里面String的构造方法

普通字符串

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

        String str2 = new String();
        System.out.println(str2);//没有输出

        String str3 = new String("pppp");
        System.out.println(str3);//pppp

字符串数组

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

        char[] array1 = {'a','b','c'};
        String str5 = new String(array1,1,2);
        System.out.println(str5);//bc

⚠String是引用类型,内部并不存储字符串本身,String类实例变量

也就是说,一个String其实是长这样的

我们来尝试分析这段代码

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

假设s1的地址是0x9,new String之后在堆中创建一个新的String,value是0x8,把"hello"扔给这个String,那这个"hello"的地址也是0x8,s1根据value的地址找到"hello"对象

字符串长度 

辨析

        String str4 = "";
        System.out.println(str4.length());
        String str5 = null;
        System.out.println(str5.length());

str4指向的是一个空的字符串,空的字符串也是字符串,也是有长度的,只不过长度为0

str5不指向任何一个字符串,那它怎么可能会有长度呢

我们也可以用isEmpty()来检验

        String str4 = "";
        System.out.println(str4.isEmpty());
        String str5 = null;
        System.out.println(str5.isEmpty());

因为str4是空的字符串,那必然返回true,而str5什么都不指向,那就会返回空指针异常 


字符串比较

equals()

辨析:这个打印的结果是true吗?

        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);

答案是false,== 比较的是s1和s2的地址,因为s1和s2本来在申请内存空间的时候,地址就不一样,怎么可能相等

那我们就要邀请String里面的一个方法.equals()来帮忙字符串比较了

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

从代码我们可以看出来,equals是按照字符串里的字符一个一个进行比较的,返回值是布尔类型

compareTo()

假设我有两个字符串,我想要比较这两个字符串谁大谁小

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

String里面实现了Comparable接口,那就可以调用compareTo方法轻松帮助我们解决问题

     System.out.println(s1.compareTo(s2));

该方法返回类型是int类型,如果s1>s2返回正数;s1=s2返回0;s1<s2返回负数

所以我们一般用>0或=0或<0来进行字符串比较

平时我们在输入验证码的时候,系统在比较两个字符串是否相等的时候是忽略大小写的

其实就是调用compareToIgnoreCase方法


字符串查找

charAt()

如果数字给大了,下标越界

indexOf()

从头到后查找字符第一次出现的下标

 也可以找子串在主串的位置

从指定位置开始查找

lastIndexOf()

倒着往回找

这就能延伸到BF算法和KMP算法,我后续会出博客,欢迎大家关注


字符串转化

1.数值和字符串转化

valueOf()方法,支持多种形式的数值,都能将其转化成字符串

        String s = String.valueOf(19.9);
        System.out.println(s);

那字符串怎么转成数字呢?

        int data = Integer.parseInt("198");
        System.out.println(data);

哪种数据类型对应哪种parsexx,假如给parseInt传入19.8,程序会报错数值格式错误

2.字符串大小写转化

toUpperCase()小写转大写;toLowerCase()大写转小写

        String s1 = "hello";
        //转变为大写不是在原来的基础上转变
        //转变成大写后是一个新的对象
        //如果只打印s1的话还只是小写
        String ret = s1.toUpperCase();
        System.out.println(ret);

3.字符串转数组

上面我们提到了数组怎么转成字符串(直接new String(array)暴力转换), 其实字符串也可以转数组(使用toCharArray())

toCharArray() 方法返回值是一个char类型的数组,所以我们要用一个新的array来接收它

4.格式化

        String s = String.format("%d-%d-%d",2023,11,9);
        System.out.println(s);


字符串替换

先来看看replace方法

比如这个,字符串里面所有的ab都被99代替了

replaceFirst():将首个内容进行替换

这里只对第一个ab进行了替换,其他ab都不动


字符串拆分

split():分割字符串

        String str = "hello abc world";
        String[] ret = str.split(" ");//将上面的字符串按照空格拆分
        for (int i = 0; i < ret.length; i++) {
            System.out.println(ret[i]);
        }

问题:

为什么用"."号分割字符串后打印出来没结果呢?

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

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

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

给你这个字符串,把每个单词拆分出来

String str = "name=zhangsan&age=18" ;

第一种写法,用|把两个分割判断符号分开来

        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++) {
            System.out.println(ret[i]);
            String x = ret[i];
            //在第一次分割的基础上按照"="进行第二次分割
            String[] ret2 = x.split("=");
            for (int j = 0; j < ret2.length; j++) {
                System.out.println(ret2[j]);
            }
        }

字符串截取

substring(): 两个参数代表区间,一个参数代表从哪里开始截

        String str = "ababc";
        String ret = str.substring(0,3);//截取字符串范围[0,3)
        System.out.println(ret);

        String ret1 = str.substring(2);
        System.out.println(ret1);

其他的方法


字符串的不可变性

String类在设计时就是不可变的

String被final修饰,表示这个类不能被继承

而String的两个实例变量均被private修饰,外部根本拿不到这两个值,也无法修改

⚠String的不可变不是因为value被final修饰了,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象的内容是可以修改的,接下来我们就来讲讲具体是怎么修改的。


String的修改

看看下面的例子

        String str = "hello";
        //System.out.println(str);//hello
        str = str + "abc";
        System.out.println(str);//helloabc

hello加上一个abc变成helloabc的过程,不是说把str的值进行修改(因为被private修饰根本拿不到value),而是创建了一个新的对象“helloabc",再让str指向这个新对象

但是如果单纯采用String产生新对象的方法来修改字符串,这样的效率是十分低下的,因为会创建一堆新对象。其实java编辑器采用了另一种方法

我们拿上面的代码去窥探它的底层 

底层看不懂?我用代码来翻译一下

    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,传统的String对象是不可变的,但是有了StringBuilder这个可变对象,字符串就可以被修改了,而且效率很高(原因看下面)。那我们接下来就来讲讲StringBuilder这个对象


StringBuilder和StringBuffer

我们首先来比较一下String自创新String对象和采用StringBuilder或StringBuffer的效率

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

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

看看内层

内层里面每一次循环StringBuilder一直存在,说明这个对象在创建之后就一直靠它来修改字符串,相比起String那种不断创建新对象再销毁旧对象的方法,这种方式显然效率更高。

StringBuffer也是这个道理

StringBuilder和StringBuffer的区别

StringBuilder的append方法底层

Stringbuffer的append方法底层

StringBuffer多了一个synchronized,表示保证线程安全,也就是说StringBuffer是一个线程安全的类

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

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

相关文章

“三位一体”超级混沌工程主要特点及功能

“三位一体”超级混沌工程X-Chaos主要包括基础故障编排、业务场景故障编排、演练场景编排、故障库管理、演练场景管理、演练计划管理、演练观测和演练报告等模块&#xff0c;支持对传统架构、云环境以及国产化基础环境的IT系统进行故障演练。本文将介绍混沌工程主要特点及主要功…

归并分治 笔记

归并分治 前置知识&#xff1a;讲解021-归并排序 原理&#xff1a; (1&#xff09;思考一个问题在大范围上的答案&#xff0c;是否等于&#xff0c;左部分的答案 右部分的答案 跨越左右产生的答案(2&#xff09;计算“跨越左右产生的答案”时&#xff0c;如果加上左、右各自…

GeoGebra:数学动画制作工具重磅来袭

【线性代数】线性代数可视化工具&#xff1a;manim manim是之前我跟大家分享的一个线性代数动画制作工具。 但我之前的描述有些许偏差&#xff0c;这里要更正一下&#xff0c;manim不仅限于制作线性代数动画&#xff0c;也可以制作数学其他学科的动画&#xff0c;例如微积分&…

Selenium是什么,带你了解自动化测试的神奇之处

一、使用测试工具 工欲善其事&#xff0c;必先利其器。在开始具体的自动化测试之前&#xff0c;我们需要做好更多的准备&#xff0c;包括以下几个方面&#xff1a; 认识自动化测试 准备自动化测试工具 使用有效的方式 针对具体的测试对象 接下来的第一部分内容&#xff0c;我…

JavaScript如何实现钟表效果,时分秒针指向当前时间,并显示当前年月日,及2024春节倒计时,源码奉上

本篇有运用jQuery&#xff0c;记得引入jQuery库&#xff0c;否则不会执行的喔~ <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> <meta name"chenc" content"Runoob"> <met…

人工智能中的基础之一——Python

Python作为一种简洁、易学、功能丰富的高级编程语言&#xff0c;被广泛应用于数据分析、人工智能、Web开发等各个领域。本文将介绍Python的基础语法和使用&#xff0c;帮助读者快速上手Python编程。 一、Python基础语法 1. 变量和数据类型 在Python中&#xff0c;可以使用变…

C#,Python实践,用CodeFormer实现人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色

无论是自己、家人或是朋友、客户的照片&#xff0c;免不了有些是黑白的、被污损的、模糊的&#xff0c;总想着修复一下。作为一个程序员 或者 程序员的家属&#xff0c;当然都有责任满足他们的需求、实现他们的想法。除了这个&#xff0c;学习了本文的成果&#xff0c;或许你还…

【Unity程序小技巧】如何消除多次Destory带来的性能消耗

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Linux学习第36天:Linux RTC 驱动实验:时间是一条流淌的河

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 RTC就是实时时钟。 本笔记主要学习Linux RTC驱动试验&#xff0c;主要内容包括Linux内核RTC驱动简介、I.MX6U内部RTC分析、RTC时间查看与设置。因为Linux内核已经…

Docker - 常用命令

Docker - 常用命令 帮助命令 docker version # 查看docker版本信息 docker info # 显示docker的系统信息&#xff0c;包括镜像和容器的数量 docker 命令 --help # 帮助命令官网帮助文档&#xff1a;https://docs.docker.com/engine/reference/commandline/cli/ 镜像…

接口测试及常用接口测试工具

首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能给你…

【算法与数据结构】77、LeetCode组合

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;如果k是固定的&#xff0c;最直接的方法就是建立k个for循环&#xff0c;将结果全部压入result容器中。…

联合阿里在职测开工程师耗时一个星期写的 【接口测试+自动化接口接口测试详解]

1&#xff1a;json模块的使用  2&#xff1a;接口自动化测试概叙 3&#xff1a;swagger工具能导出接口文档的 4:前端页面: 5:后端: 6:前端和后端的数据交互&#xff08;接口&#xff09;通过接口 7&#xff1a;接口的概念 8&#xff1a;常用的接口方式&#xff08;协议…

自动化测试中的失败截图和存log

如果我们在执行自动化测试的时候&#xff0c;希望能在失败的时候保存现场&#xff0c;方便事后分析。 对于UI自动化&#xff0c;我们希望截图在测试报告中。 对于api自动化&#xff0c;我们希望截取出错的log在测试报告中。 我开始自己蛮干&#xff0c;写了两个出错截图的方法。…

Essential Math for AI:高效的人工智能数学原理晋级读物

今天给大家介绍一本人工智能数学原理书籍&#xff1a;Essential Math for AI。作者是Hala Nelson&#xff0c;一位应用数学领域的美女博士&#xff0c;James Madison University (JMU) 大学的助理教授。 关注微信公众号&#xff1a;人工智能大讲堂&#xff0c;后台回复【ema】获…

【Android】Debug时禁用主线程ANR限制

ANR全称Application Not Response&#xff0c;指主线程超过5s无响应&#xff0c;应用会自动退出 由于这个线程&#xff0c;如果我们给主线程加了断点&#xff0c;就会触发ANR&#xff0c;导致调试时应用退出 这样调试起来会非常麻烦&#xff0c;其实对于Debug应用&#xff0c…

JVM虚拟机-虚拟机性能监控、故障处理工具

1基础故障处理工具 jps&#xff08;JVM Process Status Tool&#xff09;是&#xff1a;虚拟机进程状况工具 作用&#xff1a;可以列出正在运行的虚拟机进程&#xff0c;并显示虚拟机执行主类&#xff08;Main Class&#xff0c;main()函数所在的类&#xff09;名称以及这些进…

人工智能基础——python:Pandas与数据处理

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

CSS基础:你必须要知道的行高属性 line-height

作者:WangMin 格言:努力做好自己喜欢的每一件事 CSDN原创文章 博客地址 &#x1f449; WangMin 对于初学CSS的同学来说&#xff0c;会有很多属性相关的疑问&#xff0c;行高属性 line-height一定是其中一个&#xff0c;因为它是CSS中非常重要的一个属性&#xff0c;这个属性改变…

AlphaControls控件TsRadioGroup的使用

通常使用AlphaControls控件中的TsRadioGroup时&#xff0c;往往使用默认值&#xff0c;会造成TsRadioGroup标题被TsRadioGroup的ITEMs占用&#xff0c;严重影响美观&#xff1a; 解决方案&#xff0c;通过对TsRadioGroup的ContentVOffset属性&#xff0c;设置为10。即可立即改善…