文章目录

  • 一、String
    • 1.字符串的不可变性
    • 2.字符串的修改
    • 3.StringBuilder和StringBuffer
    • 4.【字符串练习】
      • 4.1 字符串中的第一个唯一字符
      • 4.2 字符串最后一个单词的长度
      • 4.3 验证回文串
  • 二、异常
    • 1.初识异常
    • 2.异常的分类
    • 3.异常的处理
    • 4.异常处理流程总结
    • 5.自定义异常

在上一章节中,我们已经对String类型的 常用的方法进行了学习,String的知识不止于此。本章节,我们再来对String进行探究,并学习有关异常的知识。

一、String

1.字符串的不可变性

在之前对字符串的学习中,我们了解到 字符串是一种不可变对象,即字符串不能被修改。当我们对字符串进行操作时,都会生成一个新的字符串。

是什么原因导致字符串的不可变性的呢?我们来阅读一下String类型的源码:
在这里插入图片描述
字符串不能修改的真正原因是因为:value被private修饰,在类外拿不到value的引用,并非是因为final。

2.字符串的修改

    public static void main(String[] args) {String s = "hello";//避免直接对String类型的对象进行修改,因为String的不可变性,所有的修改都会创建新对象,效率低s += " world";System.out.println(s);}

使用上面这种方法,虽然可以完成对字符串的修改,但是效率很低。

我们可以使用StringBuilder和StringBuffer对字符串进行修改。

3.StringBuilder和StringBuffer

StringBuilder和StringBuffer的大部分功能都是相同的,我们就以StringBuilder举例:
在这里插入图片描述
在这里插入图片描述

    public static void main(String[] args) {//StringBuilder和StringBuffer功能类似StringBuilder stringBuilder = new StringBuilder();StringBuilder stringBuilder1 = new StringBuilder("666");//在原数据上进行修改,不会生成新的对象//String不可变,而StringBuilder和StringBuffer可变stringBuilder1.append(888);stringBuilder1.append("222");stringBuilder1.append(888).append(99.99);System.out.println(stringBuilder1);stringBuilder1.setCharAt(1, 'M');stringBuilder1.insert(1, "==");System.out.println(stringBuilder1);stringBuilder1.reverse();System.out.println(stringBuilder1);/*** String 和 StringBuilder并不能直接转换,要想转换:* 1.String 变 StringBuilder:利用StringBuilder构造方法 或 append方法*      构造方法:StringBuilder stringBuilder1 = new StringBuilder("666");* 2.StringBuilder 变 String:toString方法*/String str = stringBuilder1.toString();System.out.println(str);}

当我们需要频繁修改字符串的内容时,建议使用StringBuilder和StringBuffer。

在使用StringBuilder和StringBuffer时我们也需要注意:String和StringBuilder并不能直接转换。

有关字符串的知识我们已经了解的差不多了,接下来我们通过几道习题尝试运用一下学过的知识。

4.【字符串练习】

4.1 字符串中的第一个唯一字符

字符串中的第一个唯一字符

在这里插入图片描述
解题思路:
在这里插入图片描述
在这道题目中,有两个点值得我们注意:

1.因为字符’a’对应的ASCII码值为97,在申请数组时,为了节省空间,我们只申请26个,后续遍历数组时,用字符对应的ASCII码值 - ‘a’ 即可。
2.在第二次遍历数组时,需要对字符串进行遍历,寻找第一个只出现一次的字符,而不应对计数数组遍历。

class Solution {public int firstUniqChar(String s) {//定义一个计数数组,下标分别对应 26个英文字母 - 'a'int[] array = new int[26];//遍历字符串,将出现的字符在计数数组中对应的位置+1for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);array[ch - 'a']++;}//再次遍历字符串,寻找字符在计数数组中是否为1//注意:遍历字符串,不是遍历计数数组!!!for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if (array[ch - 'a'] == 1) {return i;}}return -1;}
}

4.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.hasNext()) { // 注意 while 处理多个 caseString s = in.nextLine();String[] str = s.split(" ");String ss = str[str.length - 1];System.out.println(ss.length());}}
}

在这道题目中,我们使用了split方法对字符串进行分割,获取最后一个单词,计算最后一个单词的长度即可。

4.3 验证回文串

验证回文串

在这里插入图片描述
解题思路:
在这里插入图片描述

class Solution {//判断是否为合法字符public boolean isLegal(char ch) {if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z') {return true;}return false;}public boolean isPalindrome(String s) {//将所有大写字符转换为小写字符s = s.toLowerCase();int left = 0;int right = s.length() - 1;//left < right:相遇结束循环while (left < right) {//left < right:防止越界while (left < right && !isLegal(s.charAt(left))) {left++;}while (left < right && !isLegal(s.charAt(right))) {right--;}//至此,left 和 right均为合法字符if (s.charAt(left) != s.charAt(right)) {return false;} else {left++;right--;}}//循环条件不满足,结束循环,是回文串return true;}
}

在这道题目中,我们需要注意:最外层的while循环的"left < right"判断的是结束条件,而内层的while循环的"left < right"是判断是否越界(如:字符串中的字符 均为 非字母数字字符的情况)。

二、异常

1.初识异常

在Java中,将程序执行过程中发生的不正常的行为称为异常。 在之前的学习中,我们也已经遇到过很多可能会出现异常的情况:

  • 算术异常:
    在这里插入图片描述
  • 数组越界异常
    在这里插入图片描述
  • 空指针异常
    在这里插入图片描述

2.异常的分类

异常可能在编译时发生,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:编译时异常和运行时异常。

  • 编译时异常:在程序编译期间发生的异常,称为编译时异常,也称为受查异常。
  • 运行时异常:在程序执行期间发生的异常,称为运行时异常,也称为非受查异常。RuntimeException及其子类对应的异常,均称为运行时异常。

3.异常的处理

在Java中,对异常进行处理依赖于5个关键字:throw,try,catch,finally,throws。

  • try-catch捕获异常

使用 try-catch 进行防御性编程:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};//System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (ArithmeticException e) {System.out.println("捕获算术异常");} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常");} catch (NullPointerException e) {System.out.println("空指针异常");}}

将可能会出现异常的代码放在try的代码块中,使用catch匹配异常,当try中的代码出现异常时,就会寻找catch的匹配条件,如果满足,就会进入到对应的catch语句中。

try-catch 还可以与 finally 一起使用:

    public static void main(String[] args) {try {System.out.println(10 / 0);} catch (ArithmeticException e) { //catch需捕获到对应的异常,否则程序依旧异常终止e.printStackTrace(); //打印异常信息System.out.println("捕获异常");return;} finally {//finally中的代码一定会被执行,哪怕之前的代码中存在returnSystem.out.println("finally一定被执行");//不建议在finally中使用return语句}System.out.println("666");}

在使用 try - catch - finally 对异常进行捕获时,我们需要注意:

1.try代码块中,对于抛出异常位置之后的代码均不会执行。
2.如果抛出的异常的类型与catch的异常类型不匹配,则不会捕捉到异常,程序就会报错。
3.使用try-catch语句成功捕捉到异常之后,try-catch后的代码可以正常执行。
4.finally中的代码一定会被执行,哪怕之前的代码中存在return;不建议在finally中使用return语句,如果finally中和 try或catch 中均存在return语句,则执行finally中的return语句。
5.可以使用"printStackTrace"打印异常信息。

当多个异常的处理方式相同时,可以合并写为:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {System.out.println("捕获异常");} catch (NullPointerException e) {System.out.println("空指针异常");}}

Exception是所有异常的父类,当异常的处理具有父子关系时,一定是子类异常在前,父类异常在后,否则会报错:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (NullPointerException e) {System.out.println("空指针异常");} catch (Exception e) {System.out.println("异常");}}

也可以通过Exception捕获所有异常,但并不推荐,捕获到的异常太模糊。


  • throw抛出异常
    在Java中,可以借助throw关键字,抛出一个指定的异常对象:
    //通过throws抛出异常,交给调用者处理(JVM)public static void main1(String[] args) throws CloneNotSupportedException {int a = 10;if (a == 10) {//throw 常用于抛出自定义异常throw new CloneNotSupportedException("a == 10"); //编译时异常}}

注意事项:

throw:
1.throw必须写在方法体内部。
2.通过throw抛出的对象必须是Exception或Exception的子类。
3.如果抛出的对象是RuntimeException或RuntimeException的子类,则可以不用自己处理,交给JVM处理。
4.如果抛出的是编译时异常,则必须用户自己处理,否则编译不通过。
5.异常一旦抛出,其后的代码均不会执行。


throws:
1.throws用于处理编译时异常,当用户不想处理方法中的编译时异常时,就可以通过throws将异常抛给方法的调用者处理。即当前方法不处理异常,提醒方法的调用者处理异常。
2.throws必须跟在方法的参数列表之后。
3.声明的异常必须是Exception或Exception的子类。
4.如果方法内部抛出了多个异常,throws之后必须跟多个异常类型,多个异常类型之间用","隔开;如果抛出的多个异常类型之间具有父子关系,也可以直接声明父类。
5.当调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出。


throw 和 throws:
当通过throw抛出一个运行时异常时,无需进行处理;但如果抛出的是一个编译时异常,就需要对其进行处理,最简单的方式就是通过throws处理。

4.异常处理流程总结

在这里插入图片描述

5.自定义异常

在我们进行自定义异常之前,我们先来看看异常的源码是怎样的(以算术异常为例):
在这里插入图片描述
自定义异常实现方式:

1.自定义一个类,并让其继承Exception或者RuntimeException,成为异常类。
2.实现一个带有String参数类型的构造方法,参数为出现异常的原因。

我们仿照源码编写自定义异常:

//运行时异常(非受查异常):extends RuntimeException
public class myException extends RuntimeException{public myException() {}public myException(String message) {super(message);}
}

此时我们就编写好了一个自定义的运行时异常。

使用也很简单:

    //运行时异常不用throwspublic static void main(String[] args) {int a = 10;if (a == 10) {throw new myException("我的异常");}}

我们再来编写一个自定义的编译时异常:

//编译时异常(受查异常):extends Exception
public class my_Exception extends Exception{public my_Exception() {}public my_Exception(String message) {super(message);}
}

使用编译时异常:

    //编译时异常必须throwspublic static void main1(String[] args) throws my_Exception {int a = 10;if (a == 10) {throw new my_Exception("我的异常");}}

由上面两个自定义异常的例子我们可以得出:

1.自定义异常通常继承Exception或者RuntimeException。
2.继承Exception的异常类默认是受查异常。
3.继承RuntimeException的异常类默认是非受查异常。


Ending。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

梯度下降在大模型训练中的作用与实现

梯度下降&#xff08;Gradient Descent&#xff09;是深度学习中最核心的优化算法之一。大模型&#xff08;如GPT、BERT&#xff09;在训练时需要优化数十亿甚至上千亿的参数&#xff0c;而梯度下降及其变体&#xff08;如SGD、Adam&#xff09;正是实现这一优化的关键工具。它…

【JVS更新日志】开源框架、APS排产、企业计划、物联网、逻辑引擎7.30更新说明!

项目介绍 JVS是企业级数字化服务构建的基础脚手架&#xff0c;主要解决企业信息化项目交付难、实施效率低、开发成本高的问题&#xff0c;采用微服务配置化的方式&#xff0c;提供了低代码数据分析物联网的核心能力产品&#xff0c;并构建了协同办公、企业常用的管理工具等&…

Eclipse中导入新项目,右键项目没有Run on Server,Tomcat的add and remove找不到项目

原因分析没有勾选Dynamic Web Module、Java、JavaScriptDynamic Web Module版本问题解决方法Eclipse中右键项目选择Properties左侧点击project facets勾选Dynamic Web Module、Java、JavaScript&#xff0c;注意Dynamic Web Module版本问题,要和tomcat版本对应。- Dynamic Web …

IntelliJ IDEA 2025系列通用软件安装教程(Windows版)

前言 JetBrains系列开发工具&#xff08;如IntelliJ IDEA、PyCharm、WebStorm等&#xff09;是程序员们非常喜爱的集成开发环境。2025年最新版本带来了更多强大的功能和改进。本教程将详细介绍如何在Windows系统上安装JetBrains 2025系列软件。 最近挖到一个宝藏级人工智能学习…

乌鸫科技前端二面

1. 你能给我介绍一下你参与的重要项目&#xff0c;并重点介绍一下做的内容?通俗解释&#xff1a; 挑一个你觉得最拿得出手、技术含量最高的项目&#xff0c;说说这个项目是干什么的&#xff08;比如一个电商网站、一个后台管理系统&#xff09;&#xff0c;你在里面具体负责了…

《c++面向对象入门与实战》笔记

前年的书&#xff0c;翻出来整理一下7章.指针指针 sizeof为4*指针 sizeof为 所指类型的sizeof注意free后置空&#xff0c;避免野指针11章.类

easyExcel生成多个sheet的动态表头的实现

在使用 EasyExcel 实现“多个 Sheet 且每个 Sheet 表头是动态的”需求时&#xff0c;思路如下&#xff1a;✅ 实现思路概述 EasyExcel 的 ExcelWriter 支持多个 Sheet 写入。每个 Sheet&#xff1a; 使用 WriteSheet 创建&#xff1b;可以绑定一个动态生成的表头 List<List&…

SQL 连接类型示例:内连接与外连接

SQL 连接类型示例&#xff1a;内连接与外连接 示例数据表 假设我们有两个表&#xff1a; employees 表:emp_idemp_namedept_id1张三1012李四1023王五1034赵六NULLdepartments 表:dept_iddept_name101销售部102技术部104财务部1. 内连接 (INNER JOIN) 内连接只返回两个表中匹配的…

Ubuntu安装gpu驱动,cuda

系统初始化 1、安装基础软件 apt-get update apt-get -y install openssh-server openssh-client apt-utils freeipmi ipmitool sshpass ethtool zip unzip nano less git netplan.io iputils-ping mtr ipvsadm smartmontools python3-pip socat conntrack libvirt-clients li…

ctfshow_源码压缩包泄露

根据题目信息直接dirsearch解压下来一个.txt文件&#xff0c;一个index.phpflag{flag_here}不对那么就去看index.php也没有东西&#xff0c;于是查看wp发现是访问/fl000g.txt这才是对的还有很多源码泄露需要去了解• git源码泄露• svn源码泄露• DS_Store 文件泄露• 网站备份…

Python 程序设计讲义(54):Python 的函数——函数概述

Python 程序设计讲义&#xff08;54&#xff09;&#xff1a;Python 的函数——函数概述 目录Python 程序设计讲义&#xff08;54&#xff09;&#xff1a;Python 的函数——函数概述一、函数的类型1、内置函数2、自定义函数二、调用函数Python 提供了函数机制&#xff0c;把实…

学习Python中Selenium模块的基本用法(3:下载浏览器驱动续)

前一篇文章主要介绍下载针对火狐浏览器的WebDriver&#xff0c;写那篇文章时才找到能够下最新版本Chrome的WebDriver地址&#xff08;参考文献6&#xff09;&#xff0c;本文继续学习并验证针对Chrome浏览器的WebDriver下载和使用方法。Chrome的WebDriver版本与操作系统相关&am…

AIDL当Parcelable序列化的数据类通信时报“Class not found when unmarshalling“找不到该类时的解决方案

1. 报错栈 &#xff1a;cusText这个类找不到 2 16:01:29.796 1044 5718 E Parcel : Class not found when unmarshalling: com.cus.sdk.cusText 08-02 16:01:29.796 1044 5718 E Parcel : java.lang.ClassNotFoundException: com.cus.sdk.cusText 08-02 16:01:29.796 1…

Django模型查询与性能调优:告别N+1问题

文章目录一、查询基础QuerySet 详解一对多关联查询多对多关联查询二、N1查询问题问题分析检测方法解决方案三、高级查询优化values()values_list()values()和values_list()对比Q() 对象复杂查询查看生成的 SQL四、项目实战场景实战一、查询基础 QuerySet 详解 Django 中通过模…

PyTorch 中 Tensor 统计学函数及相关概念

文章目录PyTorch 中 Tensor 统计学函数及相关概念一、引言二、基础统计学函数&#xff08;一&#xff09;torch.mean()——均值计算&#xff08;二&#xff09;torch.sum()——总和计算&#xff08;三&#xff09;torch.prod()——元素积计算&#xff08;四&#xff09;torch.m…

浅拷贝与深拷贝的区别

浅拷贝和深拷贝是两种不同的对象复制方式&#xff0c;主要区别在于它们如何处理对象内部的引用类型字段。浅拷贝 (Shallow Copy)特点&#xff1a;只复制对象本身&#xff08;基本类型字段&#xff09;和对象中的引用&#xff08;地址&#xff09;不复制引用指向的实际对象原始对…

脚本统计MongoDB集合表数据量

脚本&#xff1a; #!/bin/bashipxxx.xx.xx.xx portxxxx dbxxxdb #user #passwmongo -host ${ip}:${port} <<EOF 2>/dev/null|grep -vE version|not match|session|compressors||Warning|delivers|upcoming|installation|https|switched|bye >collec use ${db}; sho…

图漾AGV行业常用相机使用文档

文章目录1.图漾相机设置IP1.1 前期准备2.FM851-E2相机2.1 FM851-E2适用场景2.2 FM851-E2 IO线和数据线定义2.2.1 IO接口定义2.2.2 数据接口线2.2.3 相机正面安装方向2.2.4 相机IO指示灯2.3 FM851-E2/FM855-E2-7相机RGB颜色异常【解决措施1】&#xff1a;【解决措施2】&#xff…

电力系统分析学习笔记(二)- 标幺值计算与变压器建模

电力系统分析学习笔记&#xff08;二&#xff09;- 标幺值计算与变压器建模 1. 电力系统参数计算的基本原理 1.1 基本级的概念与选择 基本级定义&#xff1a; 在多电压等级的电力系统中&#xff0c;需要将所有参数归算到同一个电压等级这个统一的电压等级称为基本级 基本级选择…

防火墙相关技术内容

防火墙的状态检测和会话技术一、防火墙的检测机制早期包过滤防火墙采用逐包检测机制&#xff0c;对每个报文独立检测其源地址、目的地址、端口等信息&#xff0c;根据预设规则决定转发或丢弃。安全隐患&#xff1a;仅基于单包信息判断&#xff0c;无法识别连接状态。例如&#…