【JavaSE】(8) String 类

一、String 类常用方法

1、构造方法

        常用的这4种构造方法:直接法,或者传参字符串字面量、字符数组、字节数组。

        在 JDK1.8 中,String 类的字符串实际存储在 char 数组中:

        String 类也重写了 toString 方法,所以可以直接打印 String 类,打印效果就是字符串,而非 className@hashCode 的形式:

        可以看到源码中,重写的 toString 直接返回的 this,因为 this 本身就是字符串类,println 会对 String 类进行处理,打印出字符串:

        length() 方法可以获取字符串长度,这区别于数组通过属性 length 获取长度。

 2、字符串的比较(包含字符串常量池)

        在前面学习 equals 和 compareTo 方法时知道,直接使用 == 比较,比较的是对象的地址,而非对象的内容:

 

        但通过两种构造方式得到的 String 类,比较的结果却不同,它们存在区别:

  • 法1:① 字符串常量池不存在"hello"对象 >> 在常量池创建"hello"对象 >> 在堆上创建"hello"对象 >> 在栈上创建 s1 引用,存放堆上对象地址。② 字符串常量池存在"hello"对象 >> 直接在堆上创建"hello"对象 >> 在栈上创建 s2 引用,存放堆上对象地址。

  • 法2:① 字符串常量池不存在"hello"对象 >> 在常量池创建"hello"对象 >> 在栈上创建 s3 引用,存放常量池上对象地址。② 字符串常量池存在"hello"对象 >> 在栈上创建 s4 引用,存放常量池上对象地址。

        因此,法1得到 false,法2得到 true。由此可见,将频繁使用的字符串存到字符串常量池,能够提高性能减少内存开销。参考博客:深入理解Java字符串常量池 | 二哥的Java进阶之路

        如果想将 new String("hello") 也存放到字符串常量池中,可手动地使用 intern 方法

        回到比较,如果想比较对象的内容,使用 equals 和 compareTo 方法。还有 equalsIgnoreCase 和 compareToIgnoreCase 方法,可忽略字母大小写:

3、字符串查找

        查找失败时,除了 charAt 抛出异常,其它方法都是返回 -1。

4、字符串转换

(1) 整数、浮点数、布尔值、对象、数组 >> 字符串

(2)字符串 >> 整数、浮点数、数组

(3)大小写转换

(4)格式化转换

5、字符串替换

6、字符串拆分

注,正则表达式中:

  • *、+、| 有特殊含义,需要加上 "\\"。
  • \  在 java 中要用 "\\" 表示,在正则表达式中也有特殊含义,最后为"\\\\"。
  • 正则表达式中,| 表示连字符,可连接多个分隔符。

7、字符串截取

8、字符串的不可变性

        题外话:Java 中的引用就是 C语言指针的改版,存的是对象的地址,但是它更安全,因为只允许 = 和 . 操作(除了数组,还有[ ] 操作),所以简单又不易出错。

        从 String 类的注释中可以看到,字符串是常量,它的值不可修改:

        String 类的内容是怎么做到不可修改的呢?有人说是因为 final,但并不是:

        修饰类的 final 表示 String 类不可继承;修饰 value 的 final 表示这个数组引用不可修改,并不是引用指向的内容不可修改。

        value 引用指向的字符串内容不可修改的原因

  • value 数组由 private 修饰。
  • String 类没有向外部提供修改 value 指向的对象的方法。

        字符串不可修改的缺点:每次修改字符串其实是创建一个新的对象效率低

        字符串不可修改的优点:

  • 多线程中使用 String 类更安全。(线程以后学习)
  • 方便储存在常量池。如果常量池中的字符串可修改,则会造成多个引用的变化。
  • 方便将固定 hashCode 存储在哈希表中。(哈希表以后学习)

二、可修改的字符串(StringBuilder和StringBuffer)

  • String 不可修改字符串内容,而 StringBuilder 和 StringBuffer 可修改字符串内容。
  • StringBuilder 和 StringBuffer 的功能大致相同,最大的不同是:StringBuffer 提供了 synchronized 操作,能够保证线程安全。(详情以后学习)

1、String 和 StringBuilder 的对比以及 append 方法

        可以看到当需要频繁修改字符串时,使用 StringBuilder 的效率要高很多,因为它不需要频繁创建新的对象。每次 +=,都会将旧的 s 对象自动销毁,所以大的不是空间开销,而是创建对象的时间开销。

2、capacity 和 ensureCapacity

        当用 StringBuilder 创建可修改的字符串对象时,实际会申请比初始化的字符串更大的空间capacity 方法就是获取实际的空间大小

        当字符串容量不够时,StringBuilder 会自动扩容,有时为了防止频繁扩容造成时间开销的增加,会使用 ensureCapacity 提前手动设置好比较大的字符串容量

三、String 类练习题

1、387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

思路:统计每种字母的个数,找到第一个个数为 1 的字母。

class Solution {

    public int firstUniqChar(String s) {
        int[] cnt = new int[256];
        // 统计每种字符个数
        for(int i = 0; i < s.length(); i++)
            cnt[s.charAt(i)]++;

        // 找到第一个唯一的字符
        for(int i = 0; i < s.length(); i++)
            if(cnt[s.charAt(i)] == 1)
                return i;
        
        // 未找到
        return -1;
    }
}

2、字符串最后一个单词的长度_牛客题霸_牛客网

思路:找到最后一个空格位置,根据空格位置裁剪出最后一个单词,获取长度。

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String s = in.nextLine();
            int index = s.lastIndexOf(' '); // 找到最后一个空格
            String lastWord = s.substring(index + 1, s.length()); // 裁剪出最后一个单词
            System.out.println(lastWord.length());
        }
    }
}

3、125. 验证回文串 - 力扣(LeetCode)

 

思路:先大写转小写,前、后设置一个标记移动,跳过非字母数字字符,匹配。

class Solution {
    // 判断小写字母和数字
    public boolean isValidChar(char ch) {
        if((ch >= 'a' && ch <='z') || (ch >= '0' && ch <= '9'))
            return true;
        else
            return false;
    }

    public boolean isPalindrome(String s) {
        // 大写转小写
        s = s.toLowerCase();
        int i = 0, j = s.length() - 1;
        // 前、后移动
        while(i < j){
            // 前、后跳过所有其它字符,直到遇到小写字母和数字停止
            while(!isValidChar(s.charAt(i)) && i < j) i++;
            while(!isValidChar(s.charAt(j)) && i < j) j--;
            // 存在不匹配,则否
            if(s.charAt(i) != s.charAt(j)) return false;
            // 匹配,则更新i、j
            i++;
            j--;
        }

        return true;
    }
}

四、补充 -- FittenCode 插件

        它是一个AI功能,可以预测你要写的代码,还能根据项目的内容对它提问

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

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

相关文章

JS(6)-数组

一.数组的基本使用 1.数组&#xff1a;把多个数据存到一组 每个数组都有编号&#xff0c;从零开始&#xff0c;数组的编号叫索引或下标&#xff0c;可以存放数字&#xff0c;字符串等。 2.取值 3.遍历数组&#xff1a;用循环的方法把每个数都访问到 a)练习 首先&#xff0c;定…

查看电脑或笔记本CPU的核心数方法及CPU详细信息

一、通过任务管理器查看 1.打开任务管理器 可以按下“Ctrl Shift Esc”组合键&#xff0c;或者按下“Ctrl Alt Delete”组合键后选择“任务管理器”来打开。 2.查看CPU信息 在任务管理器界面中&#xff0c;点击“性能”标签页&#xff0c;找到CPU使用记录区域&#xff0c…

Docker核心命令与Yocto项目的高效应用

随着软件开发逐渐向分布式和容器化方向演进&#xff0c;Docker 已成为主流的容器化技术之一。它通过标准化的环境配置、资源隔离和高效的部署流程&#xff0c;大幅提高了开发和构建效率。Yocto 项目作为嵌入式 Linux 系统构建工具&#xff0c;与 Docker 的结合进一步增强了开发…

08-Elasticsearch

黑马商城作为一个电商项目&#xff0c;商品的搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的&#xff0c;存在很多问题。 首先&#xff0c;查询效率较低。 由于数据库模糊查询不走索引&#xff0c;在数据量较大的时候&#xff0c;查询性能很…

MyBatis最佳实践:提升数据库交互效率的秘密武器

第一章&#xff1a;框架的概述&#xff1a; MyBatis 框架的概述&#xff1a; MyBatis 是一个优秀的基于 Java 的持久框架&#xff0c;内部对 JDBC 做了封装&#xff0c;使开发者只需要关注 SQL 语句&#xff0c;而不关注 JDBC 的代码&#xff0c;使开发变得更加的简单MyBatis 通…

Scratch全攻略:从入门到实践的编程之旅

目录 一、Scratch 基础入门1.1 Scratch 是什么1.2 安装与界面熟悉1.2.1 在线版1.2.2 离线版1.2.2.1 舞台区1.2.2.2 角色区1.2.2.3 脚本区1.2.2.4 背景区1.2.2.5 声音区 二、核心编程要素2.1 角色与舞台2.2 积木块详解2.2.1 运动类积木2.2.2 外观类积木2.2.3 声音类积木2.2.4 事…

STM32之CubeMX新建工程操作(十八)

STM32F407 系列文章 - STM32CubeMX&#xff08;十八&#xff09; 目录 前言 一、STM32CubeMX 二、新建工程 ​编辑 1.创建工程 2.选择芯片型号 3.Pinout引脚分配 1.SYS配置 2.RCC配置 3.定时器配置 4.GPIO引脚配置 5.中断配置 6.通讯接口配置 7.插件Middleware配…

Spark任务提交流程

当包含在application master中的spark-driver启动后&#xff0c;会与资源调度平台交互获取其他执行器资源&#xff0c;并通过反向注册通知对应的node节点启动执行容器。此外&#xff0c;还会根据程序的执行规划生成两个非常重要的东西&#xff0c;一个是根据spark任务执行计划生…

GenTact Toolbox:为Franka Research 3机械臂定制触觉 “皮肤” 的创新方案

前言&#xff1a; 在机器人的发展历程中&#xff0c;为其配备全身触觉皮肤一直是一项充满挑战的任务。传统的触觉皮肤设计往往采用模块化、“一刀切” 的方式&#xff0c;虽然具备一定通用性&#xff0c;但无法充分考虑机器人独特的形状以及其操作环境的特殊需求。在复杂的现实…

设计模式Python版 单例模式

文章目录 前言一、单例模式二、单例模式实现方式三、单例模式示例四、单例模式在Django框架的应用 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模…

JVM面试题解,垃圾回收之“对象存活判断”剖析

一、JVM怎么判断一个类/对象是不是垃圾&#xff1f; 先来说如何判断一个对象是不是垃圾 最常用的就是引用计数法和可达性分析 引用计数法 引用计数法为每个对象维护一个计数器来跟踪有多少个引用指向该对象。每当创建一个新的引用指向某个对象时&#xff0c;计数器加1&…

【Django开发】django美多商城项目完整开发4.0第14篇:Docker使用,1. 在Ubuntu中安装Docker【附

本教程的知识点为&#xff1a; 项目准备 项目准备 配置 1. 修改settings/dev.py 文件中的路径信息 2. INSTALLED_APPS 3. 数据库 用户部分 图片 1. 后端接口设计&#xff1a; 视图原型 2. 具体视图实现 用户部分 使用Celery完成发送 判断帐号是否存在 1. 判断用户名是否存在 后…

14-5C++的deque容器

(一&#xff09;deque的基础知识 1.deque是“double-ended queue"的缩写和vector-样都是STL的容器 2.deque是双端数组而vector是单端的 3.deque在接口上和vector非常相似&#xff0c;在许多操作的地方可以直接替换 4.deque可以随机存取元素(支持索引值直接存取&#xf…

鸿蒙仓颉环境配置(仓颉SDK下载,仓颉VsCode开发环境配置,仓颉DevEco开发环境配置)

目录 ​1&#xff09;仓颉的SDK下载 1--进入仓颉的官网 2--点击图片中的下载按钮 3--在新跳转的页面点击即刻下载 4--下载 5--找到你们自己下载好的地方 6--解压软件 2&#xff09;仓颉编程环境配置 1--找到自己的根目录 2--进入命令行窗口 3--输入 envsetup.bat 4--验证是否安…

grafana新增email告警

选择一个面板 比如cpu 新增一个临界点表达式 input选A 就是A的值达到某个临界点 触发告警 我这边IS ABOVE0.15就是cpu大于0.15%就触发报警&#xff0c;这个值怎么填看指标的值显示 这里要设置一下报警条件 这边随便配置下 配置标签和通知&#xff0c;选择你的邮件 看下告警…

springboot自动配置原理(高低版本比较)spring.factories文件的作用

SpringBootApplication public class SpringSecurityApplication {public static void main(String[] args) {SpringApplication.run(SpringSecurityApplication.class, args);}}注解SpringBootApplication Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Doc…

Spring源码03 - bean注入和生命周期

bean注入和生命周期&#xff08;面试&#xff09; 文章目录 bean注入和生命周期&#xff08;面试&#xff09;一&#xff1a;getBean的主体思路1&#xff1a;初步思路2&#xff1a;SpringBean的主体思路 二&#xff1a;Spring如何解决循环依赖问题1&#xff1a;三级Map&#xf…

vscode导入模块不显示类型注解

目录结构&#xff1a; utils.py&#xff1a; import random def select_Jrandom(i:int, m:int) -> int:"""随机选择一个不等于 i 的整数"""j iwhile j i:j int(random.uniform(0, m))return jdef clip_alpha(alpha_j:float, H:float, L:f…

浅谈机器学习之基于RNN进行充值的油费预测

浅谈机器学习之基于RNN进行充值的油费预测 引言 随着智能交通和物联网技术的发展&#xff0c;油费预测已成为研究的热点之一。准确的油费预测不仅能帮助车主合理规划出行成本&#xff0c;还可以为油价波动提供参考依据。近年来&#xff0c;递归神经网络&#xff08;RNN&#…

There is no getter for property named ‘XXX’ in ‘XXXX‘

写了一个POST方法用于新增软件描述信息&#xff0c;报错显示在我的实体类中没有这个属性的getter方法&#xff0c;实体类如下&#xff1a; 报错没有softWare这个属性的getter方法&#xff0c;但是我的实体类中本来就没有这个属性&#xff08;笑哭...) 后面查了许多资料发现&am…