java复习 05

news2026/2/28 3:23:07

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

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

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

这是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 的优先级为 10
        m1.setPriority(10);
        // 设置 m2 的优先级为 1
        m2.setPriority(1);
        // 启动线程
        m1.start();
        m2.start();
    }
}
package PTA_training.Thread_training;

public class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public 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{
    @Override
    int getTotal(){
        if (weight > 1){
            return 12 + (weight - 1) * 2;
        }else {
            return 12;
        }
    }
}
class DDExpress extends Express{
    @Override
    int 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.coloradmin.cn/o/2405264.html

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

相关文章

aardio 简单网页自动化

WebView自动化&#xff0c;以前每次重复做网页登录、搜索这些操作时都觉得好麻烦&#xff0c;现在终于能让程序替我干活了&#xff0c;赶紧记录下这个超实用的技能&#xff01; 一、初次接触WebView WebView自动化就像给程序装了个"网页浏览器"&#xff0c;第一步得…

打卡第39天:Dataset 和 Dataloader类

知识点回顾&#xff1a; 1.Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09; 2.Dataloader类 3.minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 import torch import torch.nn as nn import…

如何做好一份优秀的技术文档:专业指南与最佳实践

如何做好一份优秀的技术文档&#xff1a;专业指南与最佳实践 技术文档是产品开发、用户支持和团队协作的核心工具。高质量的技术文档能够提升开发效率、降低维护成本并改善用户体验。本文将从实践出发&#xff0c;详细讲解如何编写专业、清晰且实用的技术文档。 &#x1f31f;…

TCP相关问题 第一篇

TCP相关问题1 1.TCP主动断开连接方为什么需要等待2MSL 如上图所示:在被动链接方调用close&#xff0c;发送FIN时进入LAST_ACK状态&#xff0c;但未收到主动连接方的ack确认&#xff0c;需要被动连接方重新发送一个FIN&#xff0c;而为什么是2MSL&#xff0c;一般认为丢失ack在…

6.Pandas 数据可视化图-1

第三章 数据可视化 文章目录 目录 第三章 数据可视化 文章目录 前言 一、数据可视化 二、使用步骤 1.pyplot 1.1引入库 1.2 设置汉字字体 1.3 数据准备 1.4 设置索引列 ​编辑 1.5 调用绘图函数 2.使用seaborn绘图 2.1 安装导入seaborn 2.2 设置背景风格 2.3 调用绘图方法 2.…

软件功能测试报告都包含哪些内容?

软件功能测试报告是软件开发生命周期中的重要文档&#xff0c;主要涵盖以下关键内容&#xff1a;    1.测试概况&#xff1a;概述测试目标、范围和方法&#xff0c;确保读者对测试背景有清晰了解。 2.测试环境&#xff1a;详细描述测试所用的硬件、软件环境&#xff0c;确保…

在Vue或React项目中使用Tailwind CSS实现暗黑模式切换:从系统适配到手动控制

在现代Web开发中&#xff0c;暗黑模式(Dark Mode)已成为提升用户体验的重要功能。本文将带你使用Tailwind CSS在React项目(Vue项目类似)中实现两种暗黑模式控制方式&#xff1a; 系统自动适配 - 根据用户设备偏好自动切换手动切换 - 通过按钮让用户自由选择 一、项目准备 使…

Linux--命令行参数和环境变量

1.命令行参数 Linux 命令行参数基础 1.1参数格式 位置参数&#xff1a;无符号&#xff0c;按顺序传递&#xff08;如 ls /home/user 中 /home/user 是位置参数&#xff09; 选项参数&#xff1a; 短选项&#xff1a;以 - 开头&#xff0c;单个字母&#xff08;如 -l 表示长格…

springboot线上教学平台

摘要&#xff1a;在社会快速发展的影响下&#xff0c;使线上教学平台的管理和运营比过去十年更加理性化。依照这一现实为基础&#xff0c;设计一个快捷而又方便的网上线上教学平台系统是一项十分重要并且有价值的事情。对于传统的线上教学平台控制模型来说&#xff0c;网上线上…

mariadb5.5.56在centos7.6环境安装

mariadb5.5.56在centos7.6环境安装 1 下载安装包 https://mariadb.org/mariadb/all-releases/#5-5 2 上传安装包的服务器 mariadb-5.5.56-linux-systemd-x86_64.tar.gz 3 解压安装包 tar -zxvf mariadb-5.5.56-linux-systemd-x86_64.tar.gz mv mariadb-5.5.56-linux-syst…

打造你的 Android 图像编辑器:深入解析 PhotoEditor 开源库

&#x1f4f8; 什么是 PhotoEditor&#xff1f; PhotoEditor 是一个专为 Android 平台设计的开源图像编辑库&#xff0c;旨在为开发者提供简单易用的图像编辑功能。它支持绘图、添加文本、应用滤镜、插入表情符号和贴纸等功能&#xff0c;类似于 Instagram 的编辑体验。该库采…

Azure 虚拟机端口资源:专用 IP 和公共 IP Azure Machine Learning 计算实例BUG

## 报错无解 找不到Azure ML 计算实例关联的 NSG .env 文件和 ufw status&#xff1a; .env 文件中 EXPOSE_NGINX_PORT8080 是正确的&#xff0c;它告诉 docker-compose.yaml 将 Nginx 暴露在宿主机的 8080 端口。 sudo ufw status 显示 Status: inactive&#xff0c;意味着宿…

Java核心技术-卷I-读书笔记(第十二版)

第一章 Java程序设计概述 09年sun被oracle收购->11年java7&#xff08;简单改进&#xff09;->14年java8&#xff08;函数式编程&#xff09;->2017年java9->2018年java11->2021年java17 第二章 Java编程环境 Java9后新增JShell&#xff0c;提供类似脚本试执…

MATLAB遍历生成20到1000个节点的无线通信网络拓扑推理数据

功能&#xff1a; 遍历生成20到1000个节点的无线通信网络拓扑推理数据&#xff0c;包括网络拓扑和每个节点发射的电磁信号&#xff0c;采样率1MHz/3000&#xff0c;信号时长5.7s&#xff0c;单帧数据波形为实采 数据生成效果&#xff1a; 拓扑及空间位置&#xff1a; 节点电磁…

卫星接收天线G/T值怎么计算?附G/T计算excel表格链接

我们在进行无线通信链路设计时&#xff0c;都会涉及接收天线最重要的参数G/T。今天&#xff0c;咱们就来聊聊G/T值该怎么计算&#xff0c;计算过程中有哪些需要留意的地方&#xff0c;以及当你看到产品说明书中标注了G/T指标&#xff0c;还需要进一步了解哪些信息。 G/T的含义 …

基于dify的营养分析工作流:3分钟生成个人营养分析报告

你去医院做体检&#xff0c;需要多久拿到体检报告呢&#xff1f;医院会为每位病人做一份多维度的健康报告吗&#xff1f;"人工报告需1小时/份&#xff1f;数据误差率高达35%&#xff1f;传统工具无法个性化&#xff1f; Dify工作流AI模型的组合拳&#xff0c;正在重塑健康…

新成果:GaN基VCSEL动态物理模型开发

作为高速数据传输与光电信号处理的核心器件&#xff0c;垂直腔面发射激光器&#xff08;VCSEL&#xff09;在高速光通信、激光雷达等领域应用广泛&#xff0c;其动态特性直接关联器件调制速率及稳定性等关键参数。近期&#xff0c;天津赛米卡尔科技有限公司技术团队开发了GaN基…

Appium+python自动化(十一)- 元素定位- 下

1、 List定位 List顾名思义就是一个列表&#xff0c;在python里面也有list这一个说法&#xff0c;如果你不是很理解什么是list&#xff0c;这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合&#xff0c;那么他的个数也就成了不确定性&#xff0c;所以这里需要用复…

免费批量PDF转Word工具

免费批量PDF转Word工具 工具简介 这是一款简单易用的批量PDF转Word工具&#xff0c;支持&#xff1a; 批量转换多个PDF文件保留原始格式和布局快速高效的转换速度完全免费使用 工具地址 下载链接 网盘下载地址&#xff1a;点击下载 提取码&#xff1a;8888 功能特点 ✅…

Mac/iOS 如何解压 RAR 格式压缩包:常用工具与详细操作步骤

一、Mac 系统解压 RAR 文件之法 Mac 系统上解压 RAR 文件有多种方法&#xff0c;除了系统自带的一些简单功能外&#xff0c;还可以借助特定的软件来实现高效解压。以下将介绍几款常用工具的解压操作。 &#xff08;一&#xff09;解压专家解压步骤 解压专家 是一款在 Mac 和 …