Java奠基】玩转字符串从基础到高级的操作技巧

目录

初识String

StringBuilder

StringJoiner

字符串原理

综合练习


初识String

java.lang.String 类代表字符串,Java程序中的所有字符串文字(例如“abc”)都为此类的对象,例:

String name = "张三"

当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在,如果不存在就创建,如果存在则复用原地址。

注意:字符串的内容是不会发生改变的,它的对象在创建后不能被更改。创建对象有两种方式,一种就是上面的直接赋值方式,另一种就是通过下面 new 的方式:

构造方法说明
public String()创建空白字符串,不含任何内容
public String(String original)根据传入的字符串,创建字符串对象
public String(char[] chs)根据字符数组,创建字符串对象
public String(byte[] chs)根据字节数组,创建字符串对象

字符串的创建:以下是通过new关键字创建字符串的相关方法:

public class StringDemo {
    public static void main(String[] args) {
        // 使用new的方式来获取一个字符串对象
        // 空参构造:可以获取一个空白的字符串对象
        String s1 = new String();
        System.out.println("@"+s1+"!"); // ""
        // 传递一个字符串,根据传递的字符串内容再创建一个新的字符串对象
        String s2 = new String("abc");
        System.out.println(s2);
        // 传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象
        char[] chs = { 'a', 'b', 'c', 'd' };
        String s4 = new String(chs);
        System.out.println(s4);
        // 传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象
        byte[] bytes = { 97, 98, 99, 100 };
        String s5 = new String(bytes);
        System.out.println(s5); // 查找scall表中的数据
    }
}

字符串的比较:关于字符串的比较有以下两个注意点:

public class StringDemo {
    public static void main(String[] args) {
        // 基本数据类型比较的是数据值
        int a = 10;
        int b = 10;
        System.out.println(a == b); // true
        // 引用数据类型比较的是地址值
        String s1 = new String("abc");
        String s2 = new String("abc");
        String s3 = "abc";
        System.out.println(s1 == s2); // false
        System.out.println(s1 == s3); // false
    }
}

关于字符串的比较这里也可以采用相应的API进行使用:

public class StringDemo {
    public static void main(String[] args) {
        // 创建两个字符串对象
        String s1 = new String("abc");
        String s2 = "abc";
        String s3 = "Abc";
        // 比较字符串对象中的内容是否相等
        boolean result1 = s1.equals(s2);
        System.out.println(result1); // true
        // 比较字符串中的内容是否相等,忽略大小写
        boolean result2 = s1.equalsIgnoreCase(s3);
        System.out.println(result2); // true
    }
}

这里我们通过如下的登录账号密码的案例加深对上面的理解学习:

public class StringDemo {
    public static void main(String[] args) {
        // 定义两个变量记录正确用户名和密码
        String rightUsername = "zhangsan";
        String rightPassword = "123456";
        // 键盘录入用户名和密码
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入用户名:");
            String username = sc.next();
            System.out.println("请输入密码:");
            String password = sc.next();
            // 比较
            if (username.equals(rightUsername) && password.equals(rightPassword)) {
                System.out.println("用户登录成功!");
                break;
            } else {
                if (i == 2) {
                    System.out.println("账号"+ username+"被锁定,请联系管理员");
               } else {
                    System.out.println("用户登录失败,用户名或密码错误! 您还剩下"+(2 - i)+"次机会");
                }
            }
        }
    }
}

效果如下所示:

字符串的遍历:关于字符串的遍历可以通过如下的方式进行:

public class StringDemo {
    public static void main(String[] args) {
        // 键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();
        // 进行遍历
        for (int i = 0; i < str.length(); i++) {
            // i 依次表示字符串的每一个索引
            char c = str.charAt(i);
            System.out.println(c);
        }
    }
}

字符串统计:统计字符串中大小写字母字符数字字符出现的次数:

public class StringDemo {
    public static void main(String[] args) {
        // 键盘录入一个字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str = sc.next();
        // 定义三个计数器
        int bigCount = 0;
        int smallCount = 0;
        int numberCount = 0;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c >= 'a' && c <= 'z') { // char类型的变量参与计算的时候自动类型提升为int,查询ascii码表
                smallCount++;
            } else if (c >= 'A' && c <= 'Z') {
                bigCount++;
            } else if(c >= '0' && c <= '9') {
                numberCount++;
            }
        }
        // 输出打印
        System.out.println("小写字母有:" + smallCount + "个");
        System.out.println("大写字母有:" + bigCount + "个");
        System.out.println("数字字母有:" + numberCount + "个");
    }
}

字符串的拼接:可以通过如下案例操作实现字符串的拼接:

public class StringDemo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        String str = arrToString(arr);
        System.out.println(str);
    }
    public static String arrToString(int[] arr) {
        if (arr == null) return "";
        if (arr.length == 0) return "[]";
        String result = "[";
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                result = result + arr[i];
            } else {
                result = result + arr[i] + ", ";
            }
        }
        // 此时拼接右括号
        result = result + "]";
        return result;
    }
}

字符串的反转:关于字符串的反转,我们可以定义如下函数进行操作:

public class StringDemo {
    public static void main(String[] args) {
        String result = reverser("abc");
        System.out.println(result); // cba
    }
    public static String reverser(String str) {
        String result = "";
        for (int i = str.length() - 1; i >= 0; i--) {
            char c = str.charAt(i);
            result = result + c;
        }
        return result;
    }
}

下面是一个字符串相关转换拼接的案例:

import java.util.Scanner;

public class StringDemo {
    public static void main(String[] args) {
        // 键盘录入一个金额
        Scanner sc = new Scanner(System.in);
        int money;
        while (true) {
            System.out.println("请输入一个金额");
            money = sc.nextInt();
            if (money >= 0 && money <= 9999999) {
                break;
            } else {
                System.out.println("金额无效");
            }
        }
        // 定义一个变量用来表示钱的大写
        String moneyStr = "";
        // 得到money中的每一位数字
        while (true) {
            // 从右往左获取数据,因为右侧是数据的个位
            int ge = money % 10;
            String capitalNUmber = getCapitalNumber(ge);
            // 把转换之后的大写拼接到moneyStr当中
            moneyStr = capitalNUmber + moneyStr;
            // 去掉刚刚获取到的数据
            money = money / 10;
            // 如果数字上的每一位都获取到了,那么money记录的就是0,此时循环结束
            if (money == 0) break;
        }
        // 在前面补0,补7位
        int count = 7 - moneyStr.length();
        for (int i = 0; i < count; i++) {
            moneyStr = "零" + moneyStr;
        }
        // 插入单位
        String[] arr = { "佰", "拾", "万","仟", "佰", "拾", "元" };
        // 遍历moneyStr,依次把插入单位插入到对应的moneyStr位置上
        String result = "";
        for (int i = 0; i < moneyStr.length(); i++) {
            char c = moneyStr.charAt(i);
            result = result + c + arr[i];
        }
        // 打印最终结果
        System.out.println(result);
    }
    // 定义一个方法把数字变成大写的中文
    public static String getCapitalNumber(int number) {
        // 定义数组,让数字跟大写的中文产生一个对应关系
        String[] arr = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌" };
        // 返回结果
        return arr[number];
    }
}

StringBuilder

StringBuilder可以看成是一个容器,创建之后里面的内容是可变的。作用是提高字符串的操作效率。因为StringBuilder是Java已经写好的类,java在底层对他做了一些特殊处理,打印对象不是地址值而是属性值。

以下是StringBuilder的构造方法:

方法名说明
public StringBuilder()创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str)根据字符串的内容,来创建可变字符串对象

以下是StringBuilder的成员方法:

通过如下的代码案例进行理解:

public class StringDemo {
    public static void main(String[] args) {
        // 创建对象
        StringBuilder str = new StringBuilder("abc");
        // 添加元素
        str.append(1);
        str.append(1.2);
        str.append(true);
        System.out.println(str);
        str.reverse(); // 反转
        System.out.println(str);
        // 使用完 StringBuilder 工具之后,再把StringBuilder变回字符串
        String Str = str.toString();
        System.out.println(Str);
    }
}

StringJoiner

StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。其作用是提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。在JDK8开始出现:

以下是StringJoiner的构造方法:

方法名说明
public StringJoiner (间隔符号)创建一个StringJoiner对象,指定拼接时的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号)创建一个StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号

以下是StringJoiner的成员方法: 

方法名说明
public StringJoiner add (添加的内容)添加数据,并返回对象本身
public int length()返回长度(字符出现的个数)
public String toString()返回一个字符串 (该字符串就是拼接之后的结果)

通过如下的代码案例进行理解:

import java.util.StringJoiner;

public class StringDemo {
    public static void main(String[] args) {
        // 创建一个对象,并指定中间的间隔符号
        StringJoiner sj = new StringJoiner("---", "[", "]");
        // 添加元素
        sj.add("aaa").add("bbb").add("ccc");
        // 打印结果
        System.out.println(sj);
    }
}

字符串原理

关于字符串的原理我们需要掌握以下几个概念:

字符串存储的内存原理

直接赋值会复用字符串常量池中的,而new出来不会复用,而是开辟一个新的空间

==号比较的到底是什么?

基本数据类型比较数据值,而引用数据类型比较地址值

字符串拼接的底层原理

拼接的时候没有变量,都是字符串;触发字符串的优化机制,在编译的时候就已经是最终的结果了。

在拼接的时候有变量,JDK8以前底层会使用StringBuilder,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。

StringBuilder提高效率原理图

字符串拼接的时候,如果有变量:

JDK8以前:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。

JDK8版本:系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。

综合练习

转换罗马数字:题目要求如下:

键盘录入一个字符串

要求1:长度为小于等于9

要求2:只能是数字将内容变成罗马数字下面是阿拉伯数字跟罗马数字的对比关系:

I-1、II-2、III-3、IV-4、V-5、VI-6、VIl-7、Vl-8、Ix-9

注意点:

罗马数字里面是没有0的,如果键盘录入的数字包含0,可以变成”"(长度为0的字符串)

import java.util.Scanner;

public class StringDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str;
        while (true) {
            // 键盘录入一个字符串
            System.out.println("请输入一个字符串:");
            str = sc.next();
            // 校验字符串是否满足规则
            boolean flag = checkStr(str);
            if (flag) {
                break;
            } else {
                System.out.println("当前的字符串不符合规则,请重新输入!");
                continue;
            }
        }
        // 将内容变成罗马数字
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            int number = c - 48;
            String result = changeLuoMa(number);
            sb.append(result + ", ");
        }
        System.out.println(sb);
    }
    public static String changeLuoMa(int number) {
        // 定义一个数组,让索引跟罗马数字产生对应关系
        String[] arr = { "", "I", "II", "III", "IV", "V", "VI", "VII", "VI", "IX" };
        return arr[number];
    }
    public static boolean checkStr(String str) {
        if (str.length() > 9) return false; // 长度小于9
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c < '0' || c > '9') return false;
        }
        return true;
    }
}

调整字符串:题目要求如下:

给定两个字符串,A和 B。

A 的旋转操作就是将 A最左边的字符移动到最右边。

例如,若A='abcde',在移动一次之后结果就是'bcdea′。

如果在若干次调整操作之后,A能变成B,那么返回True,如果不能匹配成功,则返回false。

public class StringDemo {
    public static void main(String[] args) {
        // 定义两个字符串
        String strA = "abcde";
        String strB = "cdeab";
        // 调用方法进行比较
        boolean result = check(strA, strB);
        // 输出结果
        System.out.println(result);
    }
    public static boolean check(String strA, String strB) {
        for (int i = 0; i < strB.length(); i++) {
            strA = rotate(strA);
            if (strA.equals(strB)){
                return true;
            }
        }
        return false;
    }
    // 旋转字符串,把最左侧的字符,变成到最右侧
    // 形参是旋转前的字符串,返回值是旋转后的字符串
    public static String rotate(String str) {
        // 截取思路
        char first = str.charAt(0); // 获取最左侧字符
        String end = str.substring(1); // 获取剩余字符
        return end + first;
    }
}

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

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

相关文章

Java语法学习反射

Java语法学习反射 大纲 基本介绍class的介绍 具体案例 1. 基本介绍 流程图&#xff08;程序在计算机的阶段&#xff09; 反射的主要的类 这个提高效率不大 2. class的介绍 对于第三点&#xff1a;首先类只会加载一次&#xff0c;得到的class的对象&#xff0c;也只有一…

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection 1 实现尺度不变性 不管多近多远&#xff0c;多大多小都能检测出来 找到一个函数&#xff0c;实现尺度的选择特性 2 高斯偏导模版求边缘 做卷积 3 高斯二阶导拉普拉斯 看哪个信号能产生最大响应 高斯…

Linux进程创建,进程终止,进程等待,进程程序替换,简易shell代码

进程创建 fork函数初识 fork函数&#xff1a;从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;子进程中返回0&#xff0c;父进程返回子进程id&#xff0c;出错返回-1 进程调用 f…

web前端(第一天HTML)

前端是什么&#xff1f; 网页&#xff1f; 将数据以各种方式&#xff08;如&#xff1a;表格、饼图、柱状图等&#xff09;呈现给用户&#xff0c;我们就可以称之为前端。 做前端所需要的工具&#xff1f; notepad 、 editplus 、 notepad 、 vscode 、 webstorm 等&#x…

Linux:搭建docker私有仓库(registry)

当我们内部需要存储镜像时候&#xff0c;官方提供了registry搭建好直接用&#xff0c;废话少说直接操作 1.下载安装docker 在 Linux 上安装 Docker Desktop |Docker 文档https://docs.docker.com/desktop/install/linux-install/安装 Docker 引擎 |Docker 文档https://docs.do…

[C++]17:二叉树进阶

二叉树进阶 一.二叉搜索树&#xff1a;1.二叉搜索树的概念&#xff1a;2.二叉搜索树的实现---循环版本&#xff1a;1.二叉搜索树的基本结构&#xff1a;2.查找&#xff1a;3.插入&#xff1a;4.中序遍历&#xff1a;5.删除&#xff1a; 3.二叉搜索树的实现---递归版本&#xff…

HCIA-HarmonyOS设备开发认证V2.0-3.2.轻量系统内核基础-软件定时器

目录 一、软件定时器基本概念二、软件定时器运行机制三、软件定时器状态四、软件定时器模式五、软件定时器开发流程六、软件定时器使用说明七、软件定时器接口八、代码分析&#xff08;待续...&#xff09;坚持就有收获 一、软件定时器基本概念 软件定时器&#xff0c;是基于系…

java SpringBoot2.7整合Elasticsearch(ES)7 带条件分页查询与不带条件分页查询演示讲解

上文 java SpringBoot2.7整合Elasticsearch(ES)7 进行文档增删查改 我们带着大家 整合了 Elasticsearch 对索引中的文档做了 各方面操作 然后 我们来说说 分页查询 这里 为了方便大家看 我加了五条数据进去 这里 我们仍然需要带个条件 这里 我们用name Mapper 接口 加一个这…

vue3 解决ionic安卓版顶部状态栏空白问题

问题展示&#xff1a; 解决&#xff1a;引入capacitor/status-bar npm install capacitor/status-bar npx cap sync在需要设置状态栏的组件上设置背景跟颜色即可

Vue3快速上手(四)ref之基本类型响应式数据

一、ref之基本类型响应式数据 1.1 基本语法 import { ref } from vuelet x ref(初始值)console.log(xxx --> , x.value);x为一个RefImpl对象&#xff0c;该对象的value属性为实际值&#xff0c;在script里需要操作x.value来改变数据的值&#xff0c;在页面里则可以直接使…

rem基础+媒体查询+Less基础

一&#xff0c;rem基础 二&#xff0c;媒体查询 2.1什么是媒体查询 2.2语法规范 2.3媒体查询rem实现元素动态大小的变化 2.4 引入资源&#xff08;理解&#xff09; 三&#xff0c;Less基础 1 维护css的弊端 2 Less介绍 3 Less变量 变量命名规范 4 Less嵌套 5 Less…

WebSocket原理详解

目录 1.引言 1.1.使用HTTP不断轮询 1.2.长轮询 2.websocket 2.1.概述 2.2.websocket建立过程 2.3.抓包分析 2.4.websocket的消息格式 3.使用场景 4.总结 1.引言 平时我们打开网页&#xff0c;比如购物网站某宝。都是点一下列表商品&#xff0c;跳转一下网页就到了商品…

消息中间件面试篇

消息中间件 RabbitMQ 消息不丢失 可能导致消息丢失的情况&#xff1a; 生产者发送消息丢失消息队列宕机消费者服务宕机&#xff0c;未接收到消息 生产者确认机制 该机制解决了生产者发送消息有可能丢失的问题。 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程…

AWD-Test2

1.已知账号密码&#xff0c;可SSH连接进行代码审计。2.登录可万能密码进入&#xff0c;也可注册后登录。3.修改url参数&#xff0c;发现报错。确定为Linux系统4.写入一句话&#xff0c;并提交。&#xff08;也可以文件上传&#xff0c;这里采用简洁的方法&#xff09; <?p…

RPC技术分享

一、微服务与RPC技术分享 1.1 微服务简介 微服务架构是一种软件设计和开发的模式&#xff0c;将应用程序拆分为一组小型、独立的服务。每个服务运行在自己的进程中&#xff0c;并使用轻量级通信机制进行协同工作。微服务架构通过提高灵活性、可维护性和可伸缩性来改进大型系统…

LeetCode.145. 二叉树的后序遍历

题目 145. 二叉树的后序遍历 分析 上篇文章我们讲了前序遍历&#xff0c;这道题目是后序遍历。 首先要知道二叉树的后序遍历是什么&#xff1f;【左 右 根】 然后利用递归的思想&#xff0c;就可以得到这道题的答案&#xff0c;任何的递归都可以采用 栈 的结构来实现&#…

备战蓝桥杯---动态规划(入门2)

今天主要介绍区间dp比较难的题&#xff1a; 下面是分析&#xff1a; 我们如果先固定点V0&#xff0c;那我们得去枚举两个点使它构成三角形&#xff0c;同时求目标值也比较难确定&#xff08;起始与终止都带0&#xff09;&#xff0c;于是我们考虑固定边&#xff0c;我们固定v0…

16 亚稳态原理和解决方案

1. 亚稳态原理 亚稳态是指触发器无法在某个规定的时间段内到达一个可以确认的状态。在同步系统中&#xff0c;输入总是与时钟同步&#xff0c;因此寄存器的setup time和hold time是满足的&#xff0c;一般情况下是不会发生亚稳态情况的。在异步信号采集中&#xff0c;由于异步…

哈工大计算机网络考试经验及资源分享

如果你觉得资源对你有用&#xff0c;在收藏的同时不要忘记点个赞(●◡●)&#xff0c;你的支持&#xff0c;是我坚持创作的最佳动力。 哈工大计算机网络是一门重要的课程&#xff0c;对于学习计算机网络知识非常有帮助。在学习这门课程时&#xff0c;我选择了中科大zq老师的网…

Spring Boot 笔记 008 创建接口_获取用户信息

1.1.1 编写userinfo接口 1.1.2 User实体类中增加转json忽略password注释 package com.geji.pojo;import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data;import java.time.LocalDateTime;//lombok 在…