String类解析(二)可变字符串,经典算法题练习

激光条纹中心提取——Steger 激光条纹中心提取-Steger 好久没有记录了,记录一下今天学习的内容,据说Steger在激光条纹中心提取上神一般的存在。文章和代码都分享给大家了哈,其中有四个文件,3个C++,一个python,python一个抠图文件,3个c++包含背景图+原图, 单张图提取, 多张图提取。 分享代码 #include <opencv2\core.hpp> #include <opencv2\highgui.hpp> #include <opencv2\imgproc.hpp> #i 阅读详情

前言❤️❤️

hello hello💕,这里是洋不写bug~😄,欢迎大家点赞👍👍,关注😍😍,收藏🌹🌹
上篇博客解析了很多String类的方法,例如去空格,转大小写,字符替换等等,这些方法都有个特点,那就是无法修改本身的String对象,只能创建的新的String对象去接收
这篇博客就会解析可以修改的字符串StringBulider,并解析几道比较经典String类型的基础算法题目,这些题目都要用到String类的方法,就当是方法的练习🐵
请添加图片描述
🎇个人主页:洋不写bug的博客
🎇所属专栏:Java学习之旅,从入门到进阶
🎇铁汁们对于Java的各种常用核心语法(不太常用的也有😆),都可以在上面的Java专栏学习,专栏正在持续更新中🐵🐵,有问题可以写在评论区或者私信我哦~

1,String不可修改的特性

像String这样的对象,就像常量一样,里面包含的属性是不能修改的
这里说的是堆空间中String对象里面的内容是不能变的,栈空间中的引用可以改变,引用也可以指向一个新的String对象,如下图:
在这里插入图片描述



可以按住ctrl键,点进去String类中看下,里面有个字节类型的数组value,这个字节数组就持有字符串的每个字节,如下图:

在这里插入图片描述

在String类中,并没有提供修改这个value数组的public方法,因此,如果想要修改String,通常的做法就是创造一个新的String



有的铁汁会说,那我像下面这样写,最后结果也是正常的,String对象也可以修改呀

public class Test {
    public static void main(String[] args) {
        String s = "hello";
        for(int i = 0;i < 100;i++){
            s += i;
        }
        System.out.println(s);
    }
}

这个代码其实执行下来一共创建了100个String对象,每次都用s指向新创建的String对象,因此效率是极低的
那这种场景怎么办呢,就可以使用可变字符串StringBuilder

2,StringBuilder类简介

Java中提供了可变字符串StringBuilder,它的用法和String非常类似,可以方便的和String之间相互转化,而且字符串还可以修改

使用可变字符串的append方法进行拼接,这样就不需要每次拼接都创建新的对象,大大降低了开销

public class Test {
    public static void main(String[] args) {
        StringBuilder s = new StringBuilder("hello");
        for(int i = 0;i < 100;i++){
            s.append(i);
        }
        System.out.println(s);
    }
}



这里测试下,for里面i加到10万,通过执行前的时间戳减去执行后的时间戳,判断程序执行的时间(单位是ms)

使用可变字符串的时间是8ms,如下:

public class Test {
    public static void main(String[] args) {
        long beg = System.currentTimeMillis();
        StringBuilder s = new StringBuilder("hello");
        for(int i = 0;i < 10_0000;i++){
            s.append(i);
        }
        System.out.println(s);
        long end = System.currentTimeMillis();
        System.out.println(end - beg);
    }
}

在这里插入图片描述



使用不可变字符串的时间是2382ms(相差接近300倍!)

public class Test {
    public static void main(String[] args) {
        long beg = System.currentTimeMillis();
        String s = new String("hello");
        for(int i = 0;i < 10_0000;i++){
            s += i;
        }
        System.out.println(s);
        long end = System.currentTimeMillis();
        System.out.println(end - beg);
    }
}

在这里插入图片描述


除了StringBullder,还有个可变字符串StringBuffer,用法和StringBuilder,只是StringBuffer加了锁,是线程安全的(这个在后面JavaEE部分的线程中会聊到),但是会牺牲效率
在绝大多数场景下,直接用StringBuilder就可以了

String类是不可变的,计算机针对不可变的东西,就可以做出一些更好的优化,提升效率:

  • 能够更方便的存储到常量池中
  • 针对不可变的String,可以更好的计算其哈希值(后面数据结构博客中聊哈希表的时候会解析)
  • 天然线程安全(JavaEE中解析)



这里补充一个东西,铁汁们在命名引用的时候,尽量不要缩写,这样后面别人看到这个引用不知道是啥意思
下面这两种写法,一看就是第一种更好😄👍

        StringBuilder stringBuilder = new StringBuilder("hello");
        StringBuilder sb = new StringBuilder("hello");

3,字符串中的唯一字符

在这里插入图片描述
力扣链接

这个题目意思很好理解,那重点就是如何统计字符串中每个字符出现的个数呢

可以通过ASCII码值的转化来统计,这个方法在算法题中经常用到

如下图,ASCII码表里面的ASCII值是从0 - 127的,也就是128个数字,能表示所有的英文字符和符号
在这里插入图片描述



在所有算法题中,只要不特殊说明,字符串中就都是英文字符或者符号
那这个题目,我们需要统计字符串中每个字符出现的次数,那铁汁们想下能不能这样搞:

  1. 先创建一个长度为128的int类型的数组count,count[65]就表示ASCII码值为65的字符出现的次数(A的ASCII码值是65,count[65]就表示A在字符串中出现的次数)
  2. 接着利用charAt方法,从头到尾读取字符串的每个字符,那如何把字符转为ASCII码值呢?
    很简单,Java中有自动的类型转化,count数组是int类型的,直接写count['A']++,这时候就会自动把'A'按照ASCII码值转化为int类型的,也就是实际效果是count[65]++
  3. 第二步搞完后,也就记录出了每个字符在字符串中出现的次数,这时候再从头到尾取出字符串的每个字符c,直接count[c](这里同样是自动类型转换,自动把字符类型转ASCII码值)查询下这个字符出现的次数,当发现为1时就返回
  4. 如果字符串中的所有字符出现的次数都大于1,那最后就返回-1



题解代码如下所示:

class Solution {
    public int firstUniqChar(String s) {
        int[] count = new int[128];
        int n = s.length();
        for(int i = 0;i < n;i++){
            char c = s.charAt(i);
            count[c]++;
        }

        for(int i = 0;i < s.length();i++){
            char c = s.charAt(i);
            if(count[c] == 1){
                return i;
            }
        }
        return -1;
    }
}

4,字符串最后一个单词长度

在这里插入图片描述

力扣链接

这个题目直接用split按照空格进行分割,分割后会返回一个String数组,直接打印String数组最后一个元素的长度即可,非常简单

如下所示:

class Solution {
    public int lengthOfLastWord(String s) {
        String[] words = s.split(" ");
        int n = words.length;
        return words[n - 1].length();
    }
}

5,验证回文串

在这里插入图片描述
力扣链接

这个题目的意思也很好理解,忽略非字母数字字符,也不看大小写,看从左往右读和从右往左读是不是一样的

首先把所有英文字母都转为小写
可以搞个双指针(在Java中也可以说是双引用),left指向最左边,right指向最右边,接着left往右走,right往左走,判断左右指向的字符是否相同
如果直到left和right重合或者left > right时,左右指向的字符都一直相等,那就是回文串
在这里插入图片描述



那如何去忽略那些非字母数字符号呢,可以写个isValid()方法,每次先判断下left和right引用当前指向的是不是非字母数字符号,如果是的话,就跳过
题解代码如下所示:

class Solution {

    public boolean isValid(char c){
        if(c >= 'a' && c <= 'z' || c >= '0' && c <= '9'){
            return true;
        }
        return false;
    }

    public boolean isPalindrome(String s) {
        s = s.toLowerCase();
        int left = 0;
        int right = s.length() - 1;
        while(left < right){
            while(left < right && !isValid(s.charAt(left))){
                left++;
            }
            while(left < right && !isValid(s.charAt(right))){
                right--;
            }

            if(s.charAt(left) != s.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}



有两点需要注意:

  1. isValid()方法中,我们不需要去记忆这些字符的ASCII码值,直接用字符的形式写出来,编译器就知道是按照ASCII码值去比大小的
  2. 第二层whlie循环中也要加上一个left < right的判断,否则如果传入一个"!!!"字符串,那left就会一直++,直到越界

总结

这篇博客的内容量不大,Java中复习知识最好的方法,就是去搞项目或者刷算法题,在实际的使用过程中去复习,这样复习的效率是非常高的💪💪🐵

以上就是今天的所有内容啦~完结撒花~🥳🎉🎉在这里插入图片描述

概率论与数理统计基础概念与重要定义汇总 文章目录一、随机事件和概率1:互斥,对立,独立事件的定义和性质。2:概率,条件概率和五大概率公式3:古典型,几何型概率和伯努利试验 一、随机事件和概率 1:互斥,对立,独立事件的定义和性质。 互斥事件\color{red}\textbf{互斥事件}互斥事件 事件A和B的交集为空,A与B就是互斥事件,也叫互不相容事件。也可叙述为:不可能同时发生的事件。如A∩B为不可能事件(A∩B=Φ),那么称事件A与事件B互斥,其含义是:事件A与事件B在任何一次试验中不会同时发生。 则P(A+B)=P(A)+P(B)(这个公 阅读详情

相关推荐

CNN经典论文(一)LeNet

Gradient-Based Learning Applied to Document Recognition(梯度学习在文档识别中的应用) Yann LeCun, Leon Bottou, Yoshua Bengio, and Patrick Haffner 发表时间:December 1998 期刊:Proceedings of the IEEE 影响:世界上第一个卷积神经网络 论文地址:Gradient-Based Learning Applied to Document Recognition

loveling丶的博客 3597

【Java】String类字符串的解析❤

一、前言 在java中,和C语言一样,也有关于字符串的定义,并且有他自己特有的功能,下面我们一起来 学习一下。 String字符串是java中的重点,String 类表示字符串类 ,所有的字符串(如"adf")都属于此类,也就是说有" "双引号括起来的都属于此类, ...

weixin_60719453的博客 3491

多元相关性分析_PAST:最简便易用的统计学分析软件教程目录

欢迎来到PAST的世界!本教程并不是将PAST的所有功能均进行详细介绍,而只是挑选与生物、医学、微生物研究相关的统计学分析内容进行讲述。根据PAST内各项分析的标签分类,将该教程具体设置如下:PAST软件介绍PAST的基本信息数据的输入和修改数据的转换和标准化图像绘制 (Plot标签)点线图和直方图散点图条形图和箱须图饼图堆叠条形图三元相图气泡图单变量统计学分析 (Univariate标...

weixin_39605706的博客 3155

String类不可变以及不可变类总结

String类在java中是immutable(不可变),因为它被关键字final修饰。当String实例创建时就会被初始化,并且以后无法修改实例信息。String类是工程师精心设计的艺术品。 一、String为什么不可变? 要了解String类创建的实例为什么不可变,首先要知道final关键字的作用:final的意思是“最终,最后”。final关键字可以修饰类、方法...

学习记录 7527

Qt中多线程的使用(一)

我们要实现的是读取大文件qtgui.index的内容加入文本框中。 很容易想到的方法: QFile* file = new QFile("E:\qtgui.index"); file-&gt;open(QIODevice::ReadOnly); QTextStream *stream = new QTextStream(file); while(!st...

yao5hed的专栏 1万+

我爬取了某非法网贷后台系统数据,终于知道什么叫做利滚利滚利滚利了

我爬取了非法贷款的后台网站!

weixin_44042821的博客 2879

【Java】String类的理解及字符串常量池

字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。Java的String类在lang包里,java.lang.String是java字符串类,包含了字符串的值和实现字符串相关操作的一些方法;java.lang包里面的类都不需要手动导入,是由程序自动导入。String表示字符串类型,属于引用数据类型, 内部并不存储字符串本身;Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。.........

trong_ 的烂笔头 2629

SAP SD 顾问面试问题 consultant interview questionnaire

以下是我个人目前面试团队 SD顾问问题的小结,希望对大家有所帮助, 也可能有回答错误的地方,希望同行不吝赐教。 也希望各位顾问们讲你们遇到的一些面试问题做个跟贴,方便大家共同进步,谢谢。   面试问题清单:  一、销售订单类型影响: 可用性检查,交货类型,输出,信贷,定价,需求,报表,合作伙伴,文本,不完整日志,交货开票,订单开票,公司间开票,统计组,屏幕顺序组,参数文件...

weixin_33825683的博客 1809

string类练习题

本篇博客主要记录`string`类的相关`oj`题,后续会持续更新,题目为入门基础题,目的是帮助初学`string`类的友友们熟悉使用`string`类. 题目包含:字符串最后一个单词的长度、 2.反转字符串 II、字符串相加

@初阶牛的博客 1435

ZYNQ PS裸机开发RS485

RS485 是一种通用的通信标准,广泛用于数据采集和控制应用中。它的主要优点之一是它允许将多个 RS485 设备放在同一条总线上,这使得多个节点可以相互连接。RS-485是美国电子工业协会(EIA)在1983年批准了一个新的平衡传输标准(balanced transmission standard),EIA一开始将RS(Recommended Standard)做为标准的前缀,不过后来为了便于识别标准的来源,已将RS改为EIA/TIA。

baidu_34971492的博客 830

创新引入HAttention模块:提升YOLOv8小目标检测精度【YOLOv8】

YOLOv8在前几个版本的基础上进行了多项优化,特别是在模型的速度和精度上做了较大改进。改进的backbone:引入了更加高效的骨干网络(backbone)设计,如更深的网络层和更高效的特征提取模块。增强的Neck模块:使用了PANet等机制来更好地融合不同尺度的特征,增强了多尺度目标检测能力。增强的Head模块:包括多头检测头,以便针对不同大小的目标进行更精细的预测。尽管如此,YOLOv8仍面临着在小目标检测精度上不如大型目标的挑战,尤其在复杂背景或高密度目标环境下。

博客 2769

Java 中String 类的不可变性与字符串拼接解析

Java 中String 类的不可变性与字符串拼接解析

暗星涌动 1465

2025年11月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(二)

本文整理了2025年11月架构设计师考试的16-30题真题及解析,涵盖多个计算机系统知识领域。主要内容包括:Linux绝对路径以根目录开始(A);模块调用下层数量用扇出表示(B);游乐园问题通过集合运算得出10人未游玩(B);磁盘位示图计算为200字节(C);测试用例核心是输入与预期输出(D)。其他题目涉及软件可靠性测试概念(B错)、评价程序准确度排序(真实程序最高,A)、测试阶段顺序(单元→组装→系统,A)、Web服务器压力测试前置步骤(C)、分时系统响应时间影响因素(用户数量多,A)、逆向工程方法(基于

一几文的编程学习笔记。 221

String类 String 字符串的比较 String 字符串值不可变

我们经常使用String声明一个字符串,相信大家应该对这个不陌生吧,但是要是仔细看,会发现String声明时单词首字母大写,所以String本身也是一个类,但是它在使用时有较多的要求,而且在Java中也算是个比较特殊的类,那么下面我们讲讲吧。首先来看个一个程序。public class CompareStringTest { public static void main(String[] ar

The Legend of the Eagle 3629

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

浅谈String的不可变性以及String拼接的简单总结

一、String实例化的两种方式以及预备知识 1.String实例化的两种方式: ①通过字面量定义的方式 ②通过new+构造函数的方式 2.预备知识:内存解析 堆:此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。 栈:即虚拟机栈,用于存储局部变量等。局部变量存放了编译期可知长度的各种基本数据类型(boolean,byte,char,short,int,float,double,long等),对象引用(不等同于对象本身,是对象在堆内的首地址)方法执行完自动释放。 方法区:用于存放已被

weixin_46569912的博客 5650

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

c++ string substring_String 类的不可变性与字符串拼接解析

一、String 类是不可变的1.1 不可变的原因在Java 中,对于String 类的定义如下:由图可知,String 类的值存储于其私有变量value 中,而变量 value 是final 修饰的。而在Java 中,final 修饰引用变量时代表给该引用无法修改其对象但可以改变其状态。同时经过阅读源码,我们发现,在String 类中 value 是私有变量且没有提供对应的setter...

weixin_39552304的博客 1194

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

string类OJ练习题

string类相关的oj题,加强对 string 类接口使用的熟练度。

x_p96484685433的博客 821

String类为什么是不可变的,真的不可变么?

前几天,有个实习生问我,String类为什么被设计成不可变的,说他看见网上的都说可变。我看了看他,说:那篇博客你没看完吧!他挠了挠头回答说:没有!我又问他:知道string类有个变量value么?他说知道,我又问这个变量有哪些修饰符修饰的,他又挠了挠头,笑着说:忘了,好像有个private。我半开玩笑的笑着说:可以啊,这都能记着!然后让他先把bug解决了晚上在告诉他!有的小伙伴就要...

hyddhy的博客 4002

String类_练习

Edit String类_练习 String类_练习 练习1:自定义一个trim方法,去除字符串两端的空格 练习2:将一个字符串指定部分进行反转 练习3:获取一个字符串在另一个字符串中出现的次数 练习4:获取两个字符串中最大相同子串 练习1:自定义一个trim方法,去除字符串两端的空格 需求:自...

dianbangxiu3172的博客 1484

详解String类不可变的底层原理

本文深入分析了Java String类的核心特性与实现细节。主要探讨了String的不可变性、存储机制演变(从char[]到byte[])以及关键源码实现。重点解析了value字段的@Stable注解、final修饰符的作用,以及equals()和substring()方法的实现逻辑。特别指出Java9引入的紧凑字符串优化,通过动态编码选择减少内存消耗,同时保持字符串操作的高效性。这些底层设计体现了String类在性能与内存效率之间的精妙权衡。

m0_73982171的博客 1150

Java中的字符串 - String 类

本文详细介绍了Java中String类的使用方法和特性。主要内容包括:1. String的三种构造方式及其内部存储结构;2. 常用字符串操作方法,如拼接、比较、查找、转化、替换、拆分等;3. String的不可变性设计及其优势;4. StringBuilder和StringBuffer的使用场景及区别;5. 字符串处理的高效方法,推荐使用StringBuilder替代直接拼接;6. 常见面试题和练习题解析,包括字符串反转、回文判断、单词统计等。

Y409001的博客 665

String类不可变的原因及优点

首先我们想知道为什么字符串是不可变的,就要先理解字符串的概念: 字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefghij”,则s[0]=“a”。 再弄清String类不可变是什么意思,了解什么是不可变对象。  不可变对象可以理解为:如果一个对象,在它正确创建完成之后,不能再改变它的状态(包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指...

qq_36804678的博客 1111

对Java String不可变的理解

在实际Java编程中经常有这样的疑惑: java的String类为什么要设置成不可变类型? 什么是不可变对象。不可变对象有什么好处? 1、不可变对象,顾名思义就是创建后的对象不可以改变,典型的例子有java中的String类型。注意,是对象不可变,并非引用不可变。 例如:定义并初始化一个String变量s ,s是引用类型变量,“hello”是String对象;           Str...

IT界的小清流 3709

Java技术——String类为什么是不可变的

0. 前言 如果一个对象,在它创建完成之后不能再改变它的状态,包括对象内的成员变量、基本数据类型的值等等。那么这个对象就是不可变的。众所周知String类就是不可变的。转载请注明出处:1. String类为什么是不可变的首先看一下String类的源码中://JDK1.6 public final class String implements java.io.Serializab...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 2650

深耕JavaSe - 解析String类的不可变性

首先需要先理解这两个知识点: (1) 字符串常量池中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。参考文章深耕JavaSe - 解析String类字符串常量的存放位置 (2) 使用final修饰的引用类型变量不能被重新赋值,但可以改变引用类型变量所引用对象的内容 。 1、什么是不可变? String类是不可变类,即创建String对象后,该对象中的字符串是不可改变的,直到这个对象被销毁,每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然

你今天真好看呀 874

【Java小知识】String为什么不可变?改变你对String不可变的认知

String String类是final类型的,所以使用String定义的字符串是一个常量,因此他一旦创建,其内容和长度是不可改变的。真的是这样简单的吗? String不可变详解 定义字符串时,在String源码中实际是将字符串赋值给了一个char类型的数组。下面都称为字符数组。 public String(String original) { this.value = original.value; this.hash = original.hash; }

圆○的博客 4264
上一篇: 时间复杂度、空间复杂度概念,计算方法解析
下一篇: 包装类和泛型的详细解析
洋不写bug
博客等级 码龄2年 87粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值