Java(十一)---String类型

文章目录

  • 前言
  • 1.String类的重要性
  • 2.常用方法
    • 2.1.字符串的创建
    • 2.2.字符串的比较
      • 2.2.1.==比较是否引用同一个对象
      • 2.2.2.boolean equals(Object anObject) 方法:
      • 2.2.3.int CompareTo(String s)
      • 2.2.4.int compareToIgnoreCase(String str) 方法:
    • 2.3.字符串的查找
    • 2.4.字符串的转化
      • 2.4.1.数值和字符串之间转化
      • 2.4.2.大小写转化
      • 2.4.3.字符串转化为字符数组
      • 2.4.4.格式化
    • 2.5.字符串的替换
    • 2.6 字符串拆分
    • 2.7 字符串截取
    • 2.8.其他操作方法
    • 2.9.字符串的不变性
  • 3. StringBuilder和StringBuffer
    • 3.1 StringBuilder的介绍
    • 3.2 面试题:
  • 4.String OJ题


前言

上一篇我们学习了创建一个图书管理系统,更加深入地复习类和对象、面向对象,继承,多态以及接口等相关内容,今天我们学习一个新的内容—String类型


1.String类的重要性

在C语言中已经涉及到字符串了,但是在C语言中没有字符串,要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。


2.常用方法

2.1.字符串的创建

主要有三种:
1.String 变量名=“内容”;(注意是双引号)
2.String 变量名=new String(“内容”);
3.利用字符数组,创建字符串

public static void main(String[] args) {
        String str1="hello";
        String str2=new String(" world");
        char[]chars={'a','b','c','d'};
        String str3=new String(chars);
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
    }

2.2.字符串的比较

字符串的比较主要有4种方法(==,equals,compareTo,compareToIgnoreCase)

2.2.1.==比较是否引用同一个对象

public static void main(String[] args) {
        String str1=new String("hello");
        String str2=new String("hello");
        String str3=str1;
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str2==str3);
    }

在这里插入图片描述

为什么?
我们画个图来解释一下
在这里插入图片描述
由此可知,==是比较两个String类型的地址,那么如果我们只想比较两个String类型中值是否一样,那么就要使用equals方法

2.2.2.boolean equals(Object anObject) 方法:

按照字典序比较字典序:字符大小的顺序
String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较,比如: s1.equals(s2)

 public static void main(String[] args) {
        String str1=new String("hello");
        String str2=new String("hello");
        System.out.println(str1.equals(str2));
        System.out.println(str1.equals(str3));
        System.out.println(str2.equals(str3));
    }

在这里插入图片描述

2.2.3.int CompareTo(String s)

如果我们要比较两个字符串的大小,那么就不能使用equals方法,而要使用compareTo方法。

 public static void main(String[] args) {
        String s="abcd";
        String s1="agada";
        int ret=s.compareTo(s1);
        System.out.println(ret);
    }

2.2.4.int compareToIgnoreCase(String str) 方法:

与compareTo方式相同,但是忽略大小写比较。

public static void main(String[] args) {
        String s2="Admin";
        String s3="admin";
        int ret1=s2.compareToIgnoreCase(s3);
        System.out.println(ret1);
    }

在这里插入图片描述

2.3.字符串的查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法
在这里插入图片描述

有这么多的方法,具体大家自己去实践,在这只提供参考代码:

public static void main(String[] args) {
        String s="aabcabcddcba";
        //chatAt(i)返回i下标的字符
        for (int i=0;i<s.length();i++){
            System.out.print(s.charAt(i)+" ");
        }
        //indexof()
        int ret=s.indexOf('b');
        int ret1=s.indexOf("bc");
        int ret2=s.indexOf("b",4);
        int ret3=s.indexOf("dd",3);
        //lastIndexOf()从后往前找
        int ret4=s.lastIndexOf("d");
        int ret5=s.lastIndexOf('b');
        int ret6=s.lastIndexOf("cd",3);
        int ret7=s.lastIndexOf('c',4);
        System.out.println("======");
        System.out.print(ret+" ");
        System.out.print(ret1+" ");
        System.out.print(ret2+" ");
        System.out.print(ret3+" ");
        System.out.print(ret4+" ");
        System.out.print(ret5+" ");
        System.out.print(ret6+" ");
        System.out.print(ret7+" ");
    }

2.4.字符串的转化

2.4.1.数值和字符串之间转化

数值转化为字符串

public static void main(String[] args) {
        int a=10;
        double b=20.6;
        boolean flg=true;
        String s1=String.valueOf(a);
        String s2=String.valueOf(b);
        String s3=String.valueOf(flg);
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }

字符串转化为数值

public static void main(String[] args) {
        String s1="10";
        String s2="20.4";
        String s3="false";
        int a=Integer.valueOf(s1);
        double b= Double.valueOf(s2);
        boolean c=Boolean.valueOf(s3);
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }

2.4.2.大小写转化

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

    public static void main(String[] args) {
        String s1="HEllo";
        s1=s1.toLowerCase();
        System.out.println(s1);
        System.out.println("=========");` String s1=String.format("%d-%d-%d",2000,1,1);
        System.out.println(s1);
        String s2="hEllO";
        s2=s2.toUpperCase();
        System.out.println(s2);
    }

2.4.3.字符串转化为字符数组

public static void main(String[] args) {
        String s="Hello world";
        char[]chars=s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.print(chars[i]+" ");
        }
    }

2.4.4.格式化

		String s1=String.format("%d-%d-%d",2000,1,1);
        System.out.println(s1);

2.5.字符串的替换

String replaceAll(String regex, String replacement) 替换所有内容
String replaceFirst(String regex, String replacement) 替换首个内容

public static void main(String[] args) {
        String s1="ababcabdeaf";
        String ret1=s1.replaceFirst("a","b");
        System.out.println(ret1);
        System.out.println("======");
        String ret2=s1.replace('a','o');
        System.out.println(ret2);

    }

在这里插入图片描述

2.6 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
可用方法如下:

String[] split(String regex) 将字符串全部拆分
String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组

 public static void main(String[] args) {
        String s1="hello world";
        String[]strings=s1.split(" ");
        for (String s:strings){
            System.out.println(s);
        }
    }

在这里插入图片描述

public static void main(String[] args) {
        String s1="hello world hello world";
        String[]strings=s1.split(" ",2);
        for(String s:strings){
            System.out.println(s);
        }
    }

在这里插入图片描述

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.
代码示例: 拆分IP地址

 public static void main(String[] args) {
        String str = "192.168.1.1" ;
        String[] result = str.split("\\.") ;
        for(String s: result) {
            System.out.println(s);
        }
    }

在这里插入图片描述
注意事项:

  1. 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
  2. 而如果是 “” ,那么就得写成 “\\” .
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
    代码示例: 多次拆分
 public static void main(String[] args) {
        String s="name=zhangsan&age=18";
        String[]strings=s.split("&");
        for(int i=0;i<strings.length;i++){
            String[]strings1=strings[i].split("=");
            for (int j=0;j< strings1.length;j++){
                System.out.print(strings1[j]+" ");
            }
            System.out.println();
        }
    }

在这里插入图片描述
这样写比较麻烦,还有一种方式

 public static void main(String[] args) {
        String s="name=zhangsan&age=18";
        String[]strings=s.split("&|=");
        for (int i=0;i< strings.length;i++){
            System.out.println(strings[i]);
        }
    }

在这里插入图片描述

2.7 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

String substring(int beginIndex) 从指定索引截取到结尾
String substring(int beginIndex, int endIndex) 截取部分内容

 public static void main(String[] args) {
        String s="abcabcde";
        String s1=s.substring(0,3);
        String s2=s.substring(3);
        System.out.println(s1);
        System.out.println("====");
        System.out.println(s2);
    }

在这里插入图片描述
注意事项:

  1. 索引从0开始
  2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

2.8.其他操作方法

String trim() 去掉字符串中的左右空格,保留中间空格

public static void main(String[] args) {
        String s="   hel l o w  orld   ";
        System.out.println(s);
        String s1=s.trim();
        System.out.println(s1);
    }

2.9.字符串的不变性

大家会发现,许多方法我们在使用完的时候,我们要用一个字符串进行接受。这是因为String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:
1 . String类在设计时就是不可改变的,String类实现描述中已经说明了
在这里插入图片描述

String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:

  1. String类被final修饰,表明该类不能被继承
  2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中
    的内容可以修改。

2 . 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象.
以replace为例
在这里插入图片描述
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。

public static void main(String[] args) {
        final int array[] = {1,2,3,4,5};
        array[0] = 100;
        System.out.println(Arrays.toString(array));
        array = new int[]{4,5,6};
    }

会报错
在这里插入图片描述
已经初始化完了array数组,可以改变其中某个具体的值,但是就不能在进行初始化。

为什么 String 要设计成不可变的?(不可变对象的好处是什么?) (选学)

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.
    那如果想要修改字符串中内容,该如何操作呢?

2.10 字符串修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下

public static void main(String[] args) {
        String s="hello";
        s+=" world";
        System.out.println(s);
    }

其反汇编代码
在这里插入图片描述

其实等价于

public static void main(String[] args) {
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("hello");
        stringBuilder.append(" world");
        String s=stringBuilder.toString();
        System.out.println(s);
    }

通过下面的代码观察+法,和append方法的效率

 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(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(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(end - start);
    }

可以看待在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。


3. StringBuilder和StringBuffer

3.1 StringBuilder的介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大
部分功能是相同的,这里介绍 StringBuilder常用的一些方法,其它需要用到了大家可参阅StringBuilder在线文档
在这里插入图片描述
这么多方法,大家以后要是有不会的,在进行使用吧。

 public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder("hello");
        StringBuilder sb2 = sb1;
		// 追加:即尾插-->字符、字符串、整形数字
        sb1.append(' '); // hello
        sb1.append("world"); // hello world
        sb1.append(123); // hello world123
        System.out.println(sb1); // hello world123
        System.out.println(sb1 == sb2); // true
        System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h
        System.out.println(sb1.length()); // 获取字符串的有效长度14
        System.out.println(sb1.capacity()); // 获取底层数组的总大小
        sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123
        sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123
        System.out.println(sb1);
        System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置
        System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置
        sb1.deleteCharAt(0); // 删除首字符
        sb1.delete(0,5); // 删除[0, 5)范围内的字符
        String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回
        System.out.println(str);
        sb1.reverse(); // 字符串逆转
        str = sb1.toString(); // 将StringBuffer以String的方式返回
        System.out.println(str);
    }

从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。
注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
StringBuilder变为String: 调用toString()方法。

3.2 面试题:

String、StringBuffer、StringBuilder的区别
String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
StringBuffer与StringBuilder大部分功能是相似的
StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。


4.String OJ题

1.第一个只出现一次的字符
2. 最后一个单词的长度
3.检测字符串是否为回文


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

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

相关文章

单调栈原理+练习

首先用一道题引出单调栈 码蹄集 (matiji.net) 首先画一个图演示山的情况&#xff1a; 最暴力的做法自然是O(n方)的双循环遍历&#xff0c;这么做的思想是求出当前山右侧有多少座比它小的山&#xff0c;遇见第一个高度大于等于它的就停止。 但是对于我们所求的答案数&#xff…

能不能接受这些坑?买电车前一定要看

图片来源&#xff1a;汽车之家 文 | Auto芯球 作者 | 雷慢 刚有个朋友告诉我&#xff0c;买了电车后感觉被骗了&#xff0c; 很多“坑”都是他买车后才知道的。 不提前研究&#xff0c;不做功课&#xff0c;放着我这个老司机不请教&#xff0c; 这个大冤种他不当谁当&…

C# WinForm —— 25 ProgressBar 介绍与使用

1. 简介 用于显示某个操作的进度 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 pbar 开头ContextMenuStrip右键菜单Enabled控件是否可用ForeColor用于显示进度的颜色MarqueeAnimationSpeed进度条动画更新的速度&#xff0c;以毫秒为单位M…

【Python】解决Python错误报错:IndexError: tuple index out of range

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

什么是PLAB?

接上文PLAB---》 可以看到和TLAB很像&#xff0c;PLAB即 Promotion Local Allocation Buffers。用在年轻代对象晋升到老年代时。 在多线程并行执行YGC时&#xff0c;可能有很多对象需要晋升到老年代&#xff0c;此时老年代的指针就"热"起来了&#xff0c;于是搞了个…

新游启航 失落的方舟台服注册指南 一文教会你方舟台服注册

新游启航&#xff01;失落的方舟台服注册指南&#xff01;一文教会你方舟台服注册 失落的方舟作为本月最受期待游戏之一&#xff0c;在上线之际许多玩家已经有点急不可待了。这款游戏是由开发商Smile gate开发的一款MMORPG类型游戏&#xff0c;这款游戏的基本玩法与其他MMORPG…

44-1 waf绕过 - WAF的分类

一、云 WAF 通常包含在 CDN 中的 WAF。在配置云 WAF 时&#xff0c;DNS 需要解析到 CDN 的 IP 上。请求 URL 时&#xff0c;数据包会先经过云 WAF 进行检测&#xff0c;如果通过检测&#xff0c;再将数据包流向主机。 二、硬件IPS/IDS防护、硬件WAF 硬件IPS/IDS防护&#xff…

归并排序C++代码详解,思路流程+代码注释,带你完全学会归并排序

归并排序 归并排序是一种经典的排序算法&#xff0c;属于分治算法的一种。其核心思想是将一个大问题分解成若干个较小的子问题来解决&#xff0c;然后根据子问题的解构建原问题的解。在排序问题中&#xff0c;归并排序将数组分成两半&#xff0c;分别对这两半进行排序&#xf…

0基础认识C语言(理论+实操3)

所有籍籍无名的日子里 我从未看轻自己半分 小伙伴们&#xff0c;一起开始我们今天的话题吧 一、算法操作符 1.双目操作符 为何叫双目操作符呢&#xff1f;其实是因为我们进行加减乘除的时候&#xff0c;至少得需要两个数字进行这些运算&#xff0c;而这个数字就被称为操作数…

Java对sqlserver表的image字段图片读取和输出本地

Java代码实现对sqlserver数据库表的image字段图片的读取&#xff0c;和输出存储到本地 由于表image字段图片存的内容是二进制值&#xff0c;如何输出保存到本地&#xff1a; 代码示例&#xff1a;&#xff08;注&#xff1a;连接sqlserver数据库需配置其驱动文件&#xff09; …

基础—SQL—DCL(数据控制语言)之用户管理

一、引言 分类全称描述DCLData Control Language&#xff08;数据控制语言&#xff09;用来创建和管理数据库用户以及控制数据库的访问权限 1、图解 右边的是我们的 MySQL 的数据库服务器&#xff0c;左边是假设的两个用户 1、 DCL 主要控制的就是有哪些用户可以来访问这台 My…

英语翻译程序,可以对用户自己建立的词汇表进行增删查改

⑴ 自行建立一个包含若干英文单词的词汇表文件&#xff0c;系统初始化时导入内存&#xff0c;用于进行句子翻译。 ⑵ 用户可以输入单词或者句子&#xff0c;在屏幕上显示对应翻译结果。 ⑶ 用户可对词汇表进行添加和删除&#xff0c;并能将更新的词汇表存储到文件中。 #defi…

RDD实战:排序算子 - sortBy()

在本实战案例中&#xff0c;我们将使用Apache Spark的sortBy()算子来对一个包含学生信息的RDD进行排序操作。 排序规则如下&#xff1a; 首先按照性别升序排列。在性别相同的情况下&#xff0c;按照年龄降序排列。 步骤1&#xff1a;创建学生信息列表 首先&#xff0c;我们创…

《计算机工程与应用》最新投稿经验2024年5月

研二下第一次投稿&#xff0c;深度学习长时间序列预测方向&#xff0c;选择了《计算机工程与应用》期刊&#xff0c;是CSCD扩展刊北大核心&#xff0c;且在24年被EI收录等等。4.10交稿到最后5.31收到录用通知&#xff0c;历时不到2个月&#xff0c;总的来说编辑部效率确实高。 …

基于强化学习的控制率参数自主寻优

1.介绍 针对控制建模与设计场景中控制参数难以确定的普遍问题&#xff0c;提出了一种基于强化学习的控制律参数自主优化解决方案。该方案以客户设计的控制律模型为基础&#xff0c;根据自定义的控制性能指标&#xff0c;自主搜索并确定最优的、可状态依赖的控制参数组合。 可…

中建环能 | “农村生活污水治理稳质增效与智能运维技术研究及成套装备应用” 科技成果评价

中华环保联合会组织召开了中建环能科技股份有限公司申请的“农村生活污水治理稳质增效与智能运维技术研究及成套装备应用”技术成果评价会。会议由中华环保联合会水环境治理专业委员会秘书长刘愿军主持。 评审会委员 本次评价会邀请了7位相关专业领域的专家组成专家评价委员会。…

spoon工具的安装与配置

spoon对应的jdk包下载资源地址 spoon软件下载资源地址 首先需要安装jdk&#xff0c;配置java环境&#xff0c;安装好后&#xff0c;cmd一下&#xff0c;查看java -version&#xff0c;看看是否成功安装&#xff0c;如果失败&#xff0c;查看系统环境变量&#xff0c;去配置jdk…

Vue3-Vite-ts 前端生成拓扑图,复制即用

完整代码&#xff0c;复制即可用&#xff0c;样式自调 试过 jointjs dagre-d3 vis&#xff0c;好用一点 方法1&#xff1a;Vis.js npm install vis-network <template><div id"mynetwork" class"myChart" :style"{width: 100%, height: 9…

QGraphicsView实现简易地图19『迁徙图』

模仿echarts的迁徙图效果 用到了前2篇制作的散点(涟漪效果)和两年前的路径动画类&#xff1b;然尾迹效果未依附路径&#xff0c;有待优化。 动态演示效果 静态展示图片 核心代码 #pragma once #include "Item/AbstractGeoItem.h" #include "DataStruct/GeoD…

苹果电脑如何清理最近打开的文稿记录 Mac如何移除浏览痕迹保护隐私

日常使用苹果电脑的过程中&#xff0c;我们经常会打开各种文稿&#xff0c;浏览网页等操作。然而&#xff0c;这些操作可能会留下一些记录&#xff0c;涉及到个人隐私和数据安全问题。下面我们来看看苹果电脑如何清理最近打开的文稿记录&#xff0c;Mac如何移除浏览痕迹保护隐私…