Java(十一)---String类型

news2024/11/18 5:30:18

文章目录

  • 前言
  • 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.检测字符串是否为回文


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

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

相关文章

算法(十四)动态规划

算法概念 动态规划&#xff08;Dynamic Programming&#xff09;是一种分阶段求解的算法思想&#xff0c;通过拆分问题&#xff0c;定义问题状态和状态之间的关系&#xff0c;使得问题能够以递推&#xff08;分治&#xff09;的方式去解决。动态规划中有三个重点概念&#xff…

C 基础 - 预处理命令和基本语法详解

#include <stdio.h> //预处理指令int main() //函数 {printf("Hello, World!"); //输出语句return 0; //返回语句 } 目录 一.预处理指令 1.#define #ifdef #ifndef #if #else #elif #endif 2.#inlcude a.新增一个文件 b.#include c.运行结果 d.扩…

AI炒股-批量爬取网易财经的要闻板块

工作任务和目标&#xff1a;批量爬取网易财经的要闻板块 在class"tab_body current"的div标签中&#xff1b; 标题和链接在&#xff1a;<a href"https://www.163.com/dy/article/J2UIO5DD051188EA.html">华为急需找到“松弛感”</a> 第一步&…

【原创教程】MES服务器与成品打标机控制说明

1 实现的功能及应用的场合 MES即制造执行系统(manufacturing execution system,简称MES),即在加强MRP计划的执行功能,把MRP计划同车间作业现场控制,通过执行系统联系起来。 MES是一个生产管理智能化的一个系统,是用于生产时记录数据、产量等信息的智能管理系统。 该项…

WebGL画粗线

目录 前言 基本思路 求左右端点 实现 组织数据 顶点着色器计算端点坐标 效果 前言 WebGL绘制模式有点、线、面三种&#xff1b;通过点的绘制可以实现粒子系统等&#xff0c;通过线可以绘制一些连线关系&#xff1b;面就强大了&#xff0c;通过面&#xff0c;我们可以…

材质技术在AI去衣中的作用

随着人工智能技术的飞速发展&#xff0c;越来越多的应用场景开始涌现。其中&#xff0c;AI去衣技术作为一种新兴的图像处理技术&#xff0c;已经在很多领域得到了广泛的应用。而在AI去衣技术中&#xff0c;材质技术起到了至关重要的作用。本文将详细介绍材质技术在AI去衣中的作…

【前缀和 记忆化搜索】LeetCode1444. 切披萨的方案数

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 记忆化搜索 LeetCode1444. 切披萨的方案数 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; ‘A’ &#xff…

生成式AI,在云端的绽放与盛开

编辑&#xff1a;阿冒 设计&#xff1a;沐由 毫无疑问&#xff0c;生成式AI已然成为当今技术发展和应用创新的重要引擎之一。 过去的一年多时间里&#xff0c;我们每个人都在目睹和见证着生成式AI是如何以移山倒海的力量&#xff0c;为诸多行业带来革命性乃至颠覆性的变革&…

Python3位运算符

前言 本文介绍的是位运算符&#xff0c;位运算可以理解成对二进制数字上的每一个位进行操作的运算&#xff0c;位运算分为 布尔位运算符 和 移位位运算符。 文章目录 前言一、位运算概览1、布尔位运算符1&#xff09;按位与运算符 ( & )2&#xff09;按位或运算符 ( | )3…

输入输出安全防护指南

输入输出安全防护指南 在现代网络应用程序中&#xff0c;输入输出的安全性是至关重要的。未经验证的输入和未编码的输出可能导致严重的安全漏洞&#xff0c;如SQL注入、跨站脚本攻击&#xff08;XSS&#xff09;等。本文将详细讨论如何通过输入验证和输出编码来确保应用程序的…

9. C++通过epoll+fork的方式实现高性能网络服务器

epollfork 实现高性能网络服务器 一般在服务器上&#xff0c;CPU是多核的&#xff0c;上述epoll实现方式只使用了其中的一个核&#xff0c;造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…

零配件相关销售业务

测试场景CRM订单类型描述SAP订单类型描述发货开票备注零部件销售&退货服务商零配件订单标准订单&#xff08;服务商零配件&#xff09;参考DN开票YY 服务商零配件退货单退货订单(服务商零配件&#xff09;不开票退返账号金额YN服务商收到的零配件&#xff08;不能使用&…

Charles-ios无法抓包原因之一证书

VPN证书安装完成后依然无法抓包存在无网络问题 VPN安装证书后直接抓包这时候抓包接口返回无网络&#xff0c;原因是IOS通用-关于本机-证书信任设计未开启信任

最佳实践:REST API 的 HTTP 请求参数

HTTP 请求中的请求参数解释 当客户端发起 HTTP 请求 时&#xff0c;它们可以在 URL 末尾添加请求参数&#xff08;也叫查询参数或 URL 参数&#xff09;来传递数据。这些参数以键值对的形式出现在 URL 中&#xff0c;方便浏览和操作。 请求参数示例 以下是一些带有请求参数的…

c基础 - 输入输出

目录 一.scanf() 和 printf() 函数 1.printf 2.scanf 二 . getchar() & putchar() 函数 1.int getchar(void) 2.int putchar(int c) 三. gets() & puts() 函数 一.scanf() 和 printf() 函数 #include <stdio.h> 需要引入头文件,stdio.h 1.printf print…

【Linux】权限的概念

1.Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受权限限制 普通用户&#xff1a;在linux下做有限的事情&#xff0c;受权限设置。 windows下也有超级用户…

ADC数模转换器

一、ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 1、ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 2、12位逐次逼近型ADC&#xff0c;1us转换时间 3、输入电压范围&#xff1a;0~3.3V&a…

掌握 JavaScript 基本输出方法

掌握 JavaScript 基本输出方法 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 JavaScript 是一种强大且灵活的编程语言&#xff0c;广泛用于 Web 开发。通过 JavaScript&#xff…

2.2 Docker安装redis

2.2 Docker安装redis 1.安装redis docker run --restartalways -p 6379:6379 --name myredis -d redis:7.0.12 --requirepass Hgh675667%–restartalways 开机自启动 -p 6379:6379 端口映射 –name myredis 容器名称 -d redis:7.0.12 redis版本 –requirepass Hgh675667% 密…

异常处理1--5.31

try--catch--finally格式&#xff1a; try{ }catch(错误类型){ }finally{ } 执行情况&#xff1a; package javatest5;public class test {public static void main(String[] args) {int num115;int num20;try{System.out.println("商等于&#xff1a;"num1/num…