java复习 05

我的天啊一天又要过去了,没事的还有时间!!!

不要焦虑不要焦虑,事实证明只要我认真地投入进去一切都还是来得及的,代码多实操多复盘,别叽叽喳喳胡思乱想多多思考,有迷茫前害怕后的功夫已经可以学很多东西了,不许胡思乱想了快点学,,,对,加油,相信自己哦!!

---------------------------------------------------------------------------------------------------------------------------------

这是day2 写的,是的一般两天合起来更一次,一路生花~~~~❀~!!~!~!~!~!~!

加油加油加油!我的天啊期末考试慌死我了不会挂科的不会挂的不会的,,,吓鼠我了。。

pta还剩两道题目,记得看课了再做,做的太多了,今天要消化不良了。。。。。

1 设置和获取线程名称(小结)


Thread 类中设置和获取线程名称的方法

  • void setName (String name):将此线程的名称更改为等于参数 name
  • String getName ():返回此线程的名称
  • 通过构造方法也可以设置线程名称

如何获取 main () 方法所在的线程名称?

  • public static Thread currentThread ():返回对当前正在执行的线程对象的引用

2 线程调度

线程有两种调度模型~~~

  • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
  • 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些

Java 使用的是抢占式调度模型

假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU 时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到 CPU 的使用权是不一定的!!

Thread 类中设置和获取线程优先级的方法

  • public final int getPriority ():返回此线程的优先级
  • public final void setPriority (int newPriority):更改此线程的优先级

public final int getPriority()

调用这个方法时,会返回当前线程对象的优先级。

返回值是一个 int 类型,在 Java 里,线程优先级的取值范围通常是 1(最低优先级 )到 10(最高优先级 ),默认值是5,(不过不同的 JVM 实现可能在具体映射到底层系统优先级时有差异,但应用层代码遵循这个取值逻辑即可 。

通过获取优先级,我们可以在程序中判断线程当前的 “重要程度” 设定,用于一些调试、日志记录或者逻辑判断场景,比如打印线程优先级信息,辅助排查多线程执行顺序相关问题 。

public final void setPriority(int newPriority)

该方法用于更改当前线程的优先级~~~~

传入的参数 newPriority 需是在合法取值范围(1 - 10 )内的 int 值。

需要注意的是,设置优先级只是给线程调度一个 “提示”!!!!!,并非设置后高优先级线程就一定会立即执行、低优先级线程就完全无法执行,它受抢占式调度整体机制以及系统环境等影响,但合理设置优先级,能在多线程协作执行中,让关键任务线程更大概率获得 CPU 资源,提升程序整体的执行效率和业务逻辑的合理性,比如在处理紧急任务的线程上设置较高优先级,让其尽快得到执行 。

 getPriority() :

是 Thread 类中的一个实例方法,其作用是返回当前线程对象的优先级。线程的优先级是一个介于 1Thread.MIN_PRIORITY)到 10Thread.MAX_PRIORITY)之间的整数,默认优先级为 5Thread.NORM_PRIORITY)。

package PTA_training.Thread_training;public class MyThreadDemo {public static void main(String[] args) {MyThread m1 = new MyThread("啊");MyThread m2 = new MyThread("ABC");// 设置 m1 的优先级为 10m1.setPriority(10);// 设置 m2 的优先级为 1m2.setPriority(1);// 启动线程m1.start();m2.start();}
}
package PTA_training.Thread_training;public class MyThread extends Thread {public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName() + ":" + i);}}
}

3 线程控制

方法名说明
static void sleep(long millis)使当前正在执行的线程停留(暂停执行)指定的毫秒数
void join()等待这个线程死亡
void setDaemon(boolean on)将此线程标记为守护线程,当运行的线程都是守护线程时,Java 虚拟机将退出

4 消耗换行符的重要性

是的!在 Java 中使用 Scanner 时,输入流的换行符处理是非常容易出错的细节。以下是关于这个问题的深度解析和避坑指南,帮你彻底理解原理并避免类似问题:

一、为什么会出现换行符残留?

1. Scanner 的输入方法特性
  • nextInt()/nextDouble() 等方法
    只会读取有效数据部分(如数字),不会消耗数据后的换行符(\n,导致换行符残留在输入流中。
  • nextLine() 方法
    会读取一行完整的输入,包括换行符(但会自动去除换行符)。如果输入流中残留换行符,nextLine() 会直接读取空字符串。
2. 具体场景示例
  • 错误代码

    java

    int n = scanner.nextInt(); // 输入:3(回车)
    String line = scanner.nextLine(); // 此时 line 是空字符串!
    
     
    • 输入 3 后按下回车,nextInt() 读取 3,但残留 \n 在输入流中。
    • nextLine() 会直接读取这个残留的 \n(视为空行),导致 line 为空。
  • 正确做法
    在 nextInt() 后手动消耗换行符:

    java

    int n = scanner.nextInt(); 
    scanner.nextLine(); // 主动读取并丢弃残留的 \n
    String line = scanner.nextLine(); // 此时正常读取下一行输入
    

二、常见输入组合的坑与解决方案

1. 场景 1:数字 + 字符串(行输入)
  • 需求:先输入整数 n,再输入 n 行字符串(如姓名和年龄)。
  • 错误代码

    java

    int n = scanner.nextInt(); // 输入:3(回车)
    for (int i = 0; i < n; i++) {String line = scanner.nextLine(); // 第一次循环读取空字符串!// 导致 line.split(" ") 长度不足,引发 ArrayIndexOutOfBoundsException
    }
    
  • 解决方案
    在 nextInt() 后添加 scanner.nextLine() 消耗换行符:

    java

    int n = scanner.nextInt(); 
    scanner.nextLine(); // 关键!消耗残留的 \n
    for (int i = 0; i < n; i++) {String line = scanner.nextLine(); // 正常读取每一行String[] parts = line.split(" ");// ... 处理逻辑
    }
    
2. 场景 2:混合使用 next() 和 nextLine()
  • 需求:先输入单词(如姓名),再输入整行文本。
  • 错误代码

    java

    String name = scanner.next(); // 输入:lily(回车)
    String desc = scanner.nextLine(); // 直接读取空字符串!
    
  • 原因
    next() 读取到 lily 后,残留的 \n 被 nextLine() 视为空行。
  • 解决方案
    同样在 next() 后添加 scanner.nextLine() 消耗换行符(如果后续需要 nextLine()):

    java

    String name = scanner.next(); 
    scanner.nextLine(); // 消耗残留的 \n
    String desc = scanner.nextLine(); // 正常读取整行
    

三、终极避坑指南

1. 基本原则
  • 如果先调用了 nextInt()/next() 等非行读取方法,后续需要调用 nextLine() 时,必须手动消耗残留的换行符
  • **********
  • 养成习惯:在 nextInt()/next() 后,立即添加 scanner.nextLine() 来 “清理” 输入流。
2. 统一使用 nextLine() 处理输入
  • 对于数字输入,先读取整行字符串,再转为数字:

    java

    String nStr = scanner.nextLine(); // 读取整行(含回车)
    int n = Integer.parseInt(nStr); // 转为整数
    

    这样可以避免 nextInt() 遗留换行符的问题。
3. 调试技巧
  • 在怀疑输入流有残留时,添加 System.out.println("DEBUG: " + scanner.hasNextLine()); 查看是否有未读取的行。
  • 使用 scanner.hasNext() 或 scanner.hasNextInt() 预判输入类型,确保逻辑正确。

四、总结:为什么这个坑容易被忽略?

  • 换行符不可见:残留的 \n 不会在控制台显示,但会直接影响后续输入方法的行为。
  • 惯性思维:以为输入方法会自动处理所有字符,但实际上 Scanner 的不同方法对换行符的处理策略不同。

记住这个口诀:非行读取后,必消换行符

下次遇到类似问题时,先检查是否在 nextInt()/next() 后遗漏了 nextLine() 的调用~

 5 Express express;这是什么做法?划重点!

/*
7-5 快递计价器-2现需要编写一个简易快递计价程序。具体来说:1、抽象快递类Express,
其包含一个属性int weight表示快递重量(单位为kg),
一个方法getWeight()用于返回快递重量和一个抽象方法getTotal()用于计算快递运费。2、两个类继承Express,分别是:
(a)顺路快递SLExpress:计价规则为首重(1kg)12元,每增加1kg费用加2元。
(b)地地快递DDExpress:计价规则为首重(1kg)5元,每增加1kg费用加1元。3、Main:
接收用户通过控制台输入的N行信息,
自动计算每件快递的运费。输入样例:
6
SL 2
DD 2
SL 1
SL 1
SL 1
DD 3输入解释:
第1行n表示需要计算的快递件数
第2至n+1表示每个快递信息,
即选哪家快递公司 以及快递的重量(单位kg),
物品重量都是整数。输出样例:
SLExpress:14
DDExpress:6
SLExpress:12
SLExpress:12
SLExpress:12
DDExpress:7*/
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();scanner.nextLine();for (int i = 0; i < n; i++) {String line = scanner.nextLine();String [] parts = line.split(" ");String name = parts[0];int weight = Integer.parseInt(parts[1]);Express express;//划重点,我卡住的地方if (name.equals("SL")){express = new SLExpress();express.weight = weight;System.out.println("SLExpress:"+ express.getTotal());} else if (name.equals("DD")) {express = new DDExpress();express.weight = weight;System.out.println("DDExpress:"+ express.getTotal());}else{continue;}}scanner.close();}
}
class SLExpress extends Express{@Overrideint getTotal(){if (weight > 1){return 12 + (weight - 1) * 2;}else {return 12;}}
}
class DDExpress extends Express{@Overrideint getTotal(){if (weight > 1){return 5 + (weight - 1 );}else {return 5;}}
}
abstract class Express {int weight;int getWeight(){return weight;}abstract int getTotal();
}

在你之前代码里出现的 Express express; 是一个变量声明语句,这是面向对象编程里多态性的一种应用,下面为你详细解释:

1. 变量声明

Express express; 声明了一个名为 express 的变量,该变量的类型为 Express。这里的 Express 是一个抽象类,此抽象类定义了快递的通用属性与方法,像 weight 属性、getWeight() 方法以及抽象方法 getTotal()

2. 多态性的体现

多态性是面向对象编程的重要特性之一,它允许我们使用父类类型的引用去引用子类的对象。在这个场景中,Express 是父类(抽象类),SLExpress 和 DDExpress 是它的子类。

在代码里,我们依据用户输入的快递公司名称(SL 或者 DD)来创建对应的子类对象,不过把这些子类对象赋值给父类类型的引用 express,具体代码如下:

java

if (name.equals("SL")) {express = new SLExpress();
} else if (name.equals("DD")) {express = new DDExpress();
}
  • 当 name 为 "SL" 时,创建一个 SLExpress 对象,并且把这个对象赋值给 express
  • 当 name 为 "DD" 时,创建一个 DDExpress 对象,并且把这个对象赋值给 express

3. 好处

采用这种做法有以下好处:

  • 代码的可扩展性:要是后续需要添加新的快递类型(例如新的子类),仅需创建新的子类并继承 Express 类,重写 getTotal() 方法,而不用修改 Main 类里大部分的代码逻辑。
  • 代码的简洁性:能够使用统一的父类引用 express 来调用 getTotal() 方法,不用为每个子类单独编写调用逻辑。例如:

java

express.weight = weight; // 设置快递重量
int total = express.getTotal(); // 计算运费

4. 动态绑定

在运行时,Java 会依据 express 实际引用的对象类型(SLExpress 或者 DDExpress)来调用对应的 getTotal() 方法,这就是动态绑定。所以,尽管 express 是 Express 类型的引用,但调用 getTotal() 方法时会执行子类重写后的具体实现。

综上所述,Express express; 这种做法利用了多态性,提升了代码的可扩展性和简洁性。

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

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

相关文章

《Go小技巧易错点100例》第三十五篇

本期分享&#xff1a; 1.循环依赖导致栈溢出 2.无法捕获子协程的panic 循环依赖导致栈溢出 在Go语言开发中&#xff0c;我们经常会遇到结构体之间需要相互引用的情况。当两个结构体直接或间接地相互包含对方作为自己的字段时&#xff0c;就会形成循环依赖。 但是在Go语言中…

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…

.NET 9中的异常处理性能提升分析:为什么过去慢,未来快

一、为什么要关注.NET异常处理的性能 随着现代云原生、高并发、分布式场景的大量普及&#xff0c;异常处理&#xff08;Exception Handling&#xff09;早已不再只是一个冷僻的代码路径。在高复杂度的微服务、网络服务、异步编程环境下&#xff0c;服务依赖的外部资源往往不可…

第二十九章 数组

第二十九章 数组 数组。所有编程语言中都少不了数组,Shell语言也不例外,只不过支持程度非常有限。即便如此,在解决某些编程问题时,数组也能发挥大作用。 什么是数组 数组是一种可以一次存放多个值的变量,其组织形式类似与表格。数组中的每个变量叫做元素,每个元素都含…

ffmpeg(五):裁剪与合并命令

裁剪&#xff08;剪切&#xff09; 精准裁剪&#xff08;有转码&#xff0c;支持任意起止时间&#xff09; # 从第 10 秒到第 30 秒&#xff0c;重新编码 ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:30 -c:v libx264 -c:a aac output.mp4快速裁剪&#xff08;无转码&#x…

20、typedef和typename

在C中&#xff0c;typedef和typename有不同的用途和语法。以下是它们的主要区别&#xff1a; typedef typedef用于为现有类型定义一个新的名字。它通常用于简化复杂类型声明&#xff0c;使代码更易读。 示例&#xff1a; typedef unsigned long ulong; typedef int (*func_…

僵尸进程是什么?怎么回收?孤儿进程?

僵尸进程是什么&#xff1f; 僵尸进程的定义&#xff1a;对于多进程程序&#xff0c;当子进程结束运行但父进程还未读取其退出状态时&#xff0c;子进程就处于僵尸态。此时&#xff0c;内核不会立即释放该子进程的进程表表项&#xff0c;以满足父进程后续查询子进程退出信息的…

[AI绘画]sd学习记录(二)文生图参数进阶

目录 7.高分辨率修复&#xff1a;以小博大8.细化器&#xff08;Refiner&#xff09;&#xff1a;两模型接力9.随机数种子&#xff08;Seed&#xff09;&#xff1a;复现图片吧 本文接续https://blog.csdn.net/qq_23220445/article/details/148460878?spm1001.2014.3001.5501…

C++学习思路

C++知识体系详细大纲 一、基础语法 (一)数据类型 基本数据类型 整数类型(int, short, long, long long)浮点类型(float, double, long double)字符类型(char, wchar_t, char16_t, char32_t)布尔类型(bool)复合数据类型 数组结构体(struct)联合体(union)枚举类型…

34、协程

在Linux系统中&#xff0c;协程是一种轻量级的线程&#xff0c;它们允许在多个任务之间切换&#xff0c;而不需要操作系统的线程调度。协程可以分为有栈协程和无栈协程&#xff0c;以及对称协程和非对称协程。 有栈协程 有栈协程每个协程都有自己的栈空间&#xff0c;允许协程…

DeepSeek 赋能金融科技,重塑开放银行生态新图景

目录 一、金融科技开放银行生态建设的现状与挑战二、DeepSeek 技术解析2.1 DeepSeek 的技术原理与特点2.2 与其他相关技术的对比优势 三、DeepSeek 在开放银行生态建设中的具体应用场景3.1 智能客服与财富管理3.2 风控与合规管理3.3 生态协同与数据共享 四、DeepSeek 应用案例分…

【QT控件】输入类控件详解

目录 一、QLineEdit 二、Text Edit 三、Combo Box 四、Spin Box 五、Date Edit & Time Edit 六、Dial 七、Slider QT专栏&#xff1a;QT_uyeonashi的博客-CSDN博客 一、QLineEdit QLineEdit 用来表示单行输入框. 可以输入一段文本, 但是不能换行 核心属性 核心信号…

【Oracle】存储过程

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 存储过程基础概述1.1 存储过程的概念与特点1.2 存储过程的组成结构1.3 存储过程的优势 2. 基础存储过程2.1 简单存储过程2.1.1 创建第一个存储过程2.1.2 带变量的存储过程 2.2 带参数的存储过程2.2.1 输入参…

【MATLAB代码】制导方法介绍与例程——三点法|三维空间,动态目标导引(订阅专栏后可直接查看源代码)

三点法导引是一种导弹制导策略,通过计算导弹、目标和制导站之间的相对位置来确保导弹准确追踪移动目标。该方法利用三角定位和动态调整,实时更新导弹的飞行路径,以提高命中率,广泛应用于军事导弹和无人机等领域。文中有完整的matlab源代码,订阅专栏后即可查看 文章目录 代…

Servlet 快速入门

文章目录 概念SpringBoot 测试案例执行原理传统 Servlet在 SpringBoot &#xff08;嵌入式 Tomcat Spring MVC&#xff09; 中请求从浏览器到业务代码的完整步骤关键点流程图 参考 概念 运行在服务器端的小程序&#xff0c; Servlet 就是一个接口&#xff0c;定义 Java 类被浏…

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…

黄柏基因组-小檗碱生物合成的趋同进化-文献精读142

Convergent evolution of berberine biosynthesis 小檗碱生物合成的趋同进化 摘要 小檗碱是一种有效的抗菌和抗糖尿病生物碱&#xff0c;主要从不同植物谱系中提取&#xff0c;特别是从小檗属&#xff08;毛茛目&#xff0c;早期分支的真双子叶植物&#xff09;和黄柏属&…

机器学习14-迁移学习

迁移学习学习笔记 一、迁移学习概述 迁移学习是机器学习中的一个重要领域&#xff0c;它旨在解决当目标任务的训练数据有限时&#xff0c;如何利用与目标任务相关但不完全相同的源任务数据来提高学习性能的问题。在现实世界中&#xff0c;获取大量高质量的标注数据往往成本高…

013旅游网站设计技术详解:打造一站式旅游服务平台

旅游网站设计技术详解&#xff1a;打造一站式旅游服务平台 在互联网与旅游业深度融合的时代&#xff0c;旅游网站成为人们规划行程、预订服务的重要工具。一个功能完备的旅游网站&#xff0c;通过用户管理、订单管理等核心模块&#xff0c;实现用户与管理员的高效交互。本文将…

量子计算+AI:特征选择与神经网络优化创新应用

在由玻色量子协办的第二届APMCM“五岳杯”量子计算挑战赛中&#xff0c;来自北京理工大学的Q-Masterminds团队摘取了银奖。该团队由北京理工大学张玉利教授指导&#xff0c;依托玻色量子550计算量子比特的相干光量子计算机&#xff0c;将量子计算技术集成到特征选择和神经网络剪…