JAVA快速入门到精通牛客零基础刷题指南:35~37 手把手带刷:常用API,日期工具

JAVA快速入门到精通牛客零基础刷题指南:35~37 手把手带刷:常用API,日期工具

常用API

日期工具

Date

Date类用来处理日期和时间,但是该类的大部分构造器、方法均以过时。

- 常用的构造方法
// 创建代表当前时间的Date对象,底层调用System类获取当前时间毫秒数。 public Date() { } // 根据指定的时间毫秒数创建Date对象,参数为时间的毫秒数。 public Date(long date) { }
- 常用的成员方法
// 判断该时间是否在指定时间之后 public boolean after(Date when) { } // 判断该时间是否在指定时间之前 public boolean before(Date when) { } // 返回该时间的毫秒数 public long getTime() { } // 以毫秒数的形式,设置该Date对象所代表的时间。 public void setTime(long time) { }

Calendar

  • 相比于Date类,Calendar类可以更好地处理日期和时间。
  • Calendar是一个抽象类,所以不能通过构造器创建Calendar对象。
  • Calendar类提供了静态方法getInstance(),用以创建实例。
- Calendar类提供了与Date互转的方法
// 返回Date public final Date getTime() { } // 将Date转为Calendar public final void setTime(Date date) { }
- Calendar类常用的成员方法
// 返回指定字段的值 public int get(int field) {} // 给指定的字段设置一个值 public void set(int field, int amount) {} // 设置年月日的值 public void set(int year, int month, int date) {} // 设置年月日时分秒的值 public void set(int year, int month, int date, int hourOfDay, int minute, int second) {}
- Calendar类常用的静态变量
YEAR, MONTH, DATE, HOUR, MINITE, SECOND, MILLISECOND

DateFormat

DateFormat用于实现日期的格式化,它是一个抽象类,提供了如下静态方法以创建实例:

// 返回日期格式器 public final static DateFormat getDateInstance() {} // 返回时间格式器 public final static DateFormat getTimeInstance() {} // 返回日期时间格式器 public final static DateFormat getDateTimeInstance() {}

同时,DateFormat提供了如下常用的成员方法:

// 将传入的日期格式化为字符串 public final String format(Date date) {} // 将传入的格式字符串解析为日期 public Date parse(String source) throws ParseException {}

SimpleDateFormat

SimpleDateFormat是DateFormat的子类,提供了更简单的格式化方案,该类提供了如下常用的构造器,常用的成员方法则与DateFormat一致。

// pattern是一个日期模板字符串,如“yyyy-MM-dd HH:mm:ss” public SimpleDateFormat(String pattern) {}

JAVA35 输出某一年的各个月份的天数

Calendar calendar=Calendar.getInstance(); for(int month=1;month<=12;month++){ calendar.set(year,month,0); System.out.println(year+"年"+month+"月:"+calendar.get(calendar.DAY_OF_MONTH)+"天"); }

DAY_OF_MONTHjava.util.Calendar 类的静态常量(int 类型)

Calendar 的月份是 0 基索引:0 代表 1 月,1 代表 2 月,……,11 代表 12 月,这是 Calendar 最经典的 “坑”

日期传入 0 的特殊规则:Calendar 的set方法中,日期字段传入0,代表取「上一个月的最后一天」

举个例子帮你理解:

  • month=1时,set(year, 1, 0) → 月份 1 对应日历的 2 月,日期 0 → 自动回退到 2 月的上一个月(1 月)的最后一天。
  • 此时调用get(Calendar.DAY_OF_MONTH),拿到的就是 1 月最后一天的数值,也就是 1 月的总天数。
  • 同理,month=12时,set(year,12,0) → 月份 12 对应次年 1 月,日期 0 → 回退到当年 12 月的最后一天,拿到 12 月的总天数。

JAVA36 日期换算

//将输入的日期用空格分割成字符串数组 String[] arr=str1.split(" "); //如果不是6位长度,则输入不正常 if(arr.length!=6){ System.out.println("您输入的数据不合理"); } else{ //将日期调整成"yyyy-MM-dd HH:mm:ss"的格式 String str=arr[0]+"-"+arr[1]+"-"+arr[2]+" "+arr[3]+":"+arr[4]+":"+arr[5]; //解析日期 Date date=sdf.parse(str); //输出北京时间 System.out.println("北京时间为:"+sdf.format(date.getTime())); //输出纽约时间 System.out.println("纽约时间为:"+sdf.format(date.getTime()-(long)12*60*60*1000)); }

parseSimpleDateFormat类的核心方法,作用是把符合指定格式的「日期时间字符串」,解析转换为java.util.Date日期对象,是「字符串→日期对象」的转换方法。

formatparse的反向操作,作用是Date对象 /long类型的时间戳,按照sdf指定的格式模板,转换为人类可读的日期时间字符串

强转long的 2 个核心原因
原因 1:从根源上规避整数溢出,是行业通用安全规范

如果不加强转,12*60*60*1000的所有操作数都是int,运算结果也是int。虽然 12 小时的毫秒数 43200000,刚好在int范围内,但这是非常脆弱的写法

  • 若后续修改数值(比如计算 30 天、100 天的毫秒数),30*24*60*60*1000=2592000000,已经超出int最大值,会直接溢出变成负数-1702967296,导致时间计算完全错误。

而把第一个数强转为(long)12后:

  • 第一个操作数变成long类型,后续所有乘法运算都会自动触发类型提升,全程以long类型运算,无论数值多大,都不会发生溢出。
  • 这是 Java 处理时间毫秒数的通用最佳实践,因为时间戳本身就是long类型,加减的数值也必须保证是long类型,从根源上避免 bug。
原因 2:和date.getTime()long类型匹配,避免隐式转换风险

date.getTime()返回的是long类型(64 位整数),如果减数是int类型,Java 会自动把int提升为long再做减法。

异常处理

  • Java语言具有如下的异常处理机制:当程序运行出现意外情形时,系统会自动生成一个异常对象来通知程序。
  • 在程序中,我们可以使用特定的语句来捕获异常对象,读取对象中的信息,进而做出处理。
  • 也可以使用特定的语句抛出异常对象,将这个异常对象交给程序的调用者处理。

异常的继承体系

- 所有的非正常情况被分为两类:

错误(Error)和异常(Exception),其中Error代表虚拟机相关问题,一般无法处理,也无需处理。

- 所有的 Exception 被分为两类
  • RuntimeException,代表运行时异常,程序可以显式处理这种异常,也可以不处理,而是交给顶层调用者统一处理。
  • 非运行时异常(Checked异常),程序必须显式地处理这种异常,否则在编译阶段会发生错误,导致程序无法通过编译。

捕获异常

语法:
try { 业务逻辑代码 } catch (AException e) { A异常的处理代码 } catch (BException e) { B异常的处理代码 } ... finally { 回收资源代码 }
说明:
1. 无论哪行代码发生异常,系统都会生成一个异常对象,这与try...catch...语句没有关系;

2. 若程序没有对这个异常对象做任何处理,则程序在此退出;

3. 创建异常对象后,JVM会寻找可以处理它的catch块,并将异常对象交给这个catch块去处理;

4. 程序应该先处理小异常、再处理大异常,即将处理父类异常的catch块放在处理子类异常的catch块之后;

5. finally块中代码总是会被执行,它必须位于try、catch之后,通常用来释放资源;

6. try是必须的,catch、finally是可选的,但catch、finally二者之中至少要出现一个。

声明抛出异常

语法:
throws ExceptionClass1, ExceptionClass2, ...
说明:
1. throws语句用于标识某方法可能抛出的异常,它必须位于方法签名之后;

2. throws语句声明抛出异常后,程序中旧无需使用try语句捕获该异常了;

3. 在重写时,子类方法声明抛出的异常类型不能比父类方法声明抛出的异常类型大。

抛出异常

语法:
throw ExceptionInstance;
说明:
1. throw语句用于在程序中主动抛出一个异常;

2. throw语句抛出的不是异常类型,而是一个异常实例;

3. 对于主动抛出的异常,也可以采用try块捕获,或者采用throws语句向外抛出。

异常的处理原则

1. 不要多度的使用异常:

不要用异常处理代替错误处理代码,不要用异常处理代替流程控制语句;

2. 不要忽略捕获的异常:

对于捕获到的异常,要进行合适的修复,对于不能处理的部分,应该抛出新的异常;

3. 不要直接捕获所有的异常:

应对不同的异常做出有针对性的处理,而捕获所有的异常,容易压制(丢失)异常;

4. 不要使用过于庞大的try块:

庞大的try块会导致业务过于复杂,不利于分析异常的原因,也不利于程序的阅读及维护。

JAVA37 判断学生成绩

import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int score = scanner.nextInt(); try{ //如果考试成绩在0-100之间,直接输出 if(score>=0&&score<=100){ System.out.println(score); } //否则抛异常 else{ throw new ScoreException("分数不合法"); } } //捕获到异常,输出错误信息 catch(ScoreException e){ System.out.println(e.getMessage()); } } } class ScoreException extends Exception{ //利用父类构造方法,初始化信息 ScoreException(String message){ super(message); } } 

getMessage():获取异常对象中携带的、自定义的异常详细描述文本

  • 当分数不合法时,new ScoreException("分数不合法") 会创建一个异常对象,把"分数不合法"通过构造方法,最终存到detailMessage里。
  • catch块捕获到这个异常对象,赋值给变量str
  • str.getMessage() 会读取异常对象里存储的detailMessage,也就是传入的"分数不合法",最终打印输出。
super(message) 的核心作用:“让父类帮忙初始化数据”

super 在这里的意思是 “父类的”,super(message) 就是 “调用父类中接收一个 String 参数的构造方法”。

public ScoreException(String message){ super(message); // 等价于:调用 Exception(String message) 这个构造方法 }
为什么必须写 super(message)?(不写会怎样?)

父类数据的封装性Throwable 里的 detailMessage 是一个 private(私有)变量。子类 ScoreException无权直接修改它。所以必须通过父类提供的 “构造方法入口”(即 super(message))来间接赋值。

如果不写,信息就丢了如果你只写 super()(不传参数),或者干脆不写 super(编译器会自动补一个无参的 super()),那么父类里的 detailMessage 就会是 null

super 关键字的两种常见用法

用法

示例

含义

1. 调用父类构造方法

super(message);

在子类构造方法的第一行调用,用于初始化父类的成员变量。

2. 调用父类的普通方法/变量

super.someMethod();

在子类方法中调用父类被重写(Override)的方法,或者访问父类的成员变量。

Read more

主流 AI 插件 之一的 Copilot 介绍

主流 AI 插件 之一的 Copilot 介绍

Copilot 是微软推出的一款人工智能助手,旨在通过自然语言交互帮助您提升工作效率和创造力,覆盖多平台(网页端、桌面端、移动端、Edge 浏览器等),提供智能问答、内容生成、代码辅助等功能。其核心定位为“日常 AI 伴侣”,旨在通过自然语言交互提升工作与生活效率。         ⚠️ 注意:自 2024 年起,Copilot 已从独立插件全面整合进 GitHub Enterprise 与 Microsoft 365 开发者计划,部分高级功能(如多文件协同编辑、Agent 模式)需订阅 Copilot Pro 或企业版。 一、Copilot 官网与介绍 1.1 Microsoft Copilot • 定位:微软旗下AI助手,适用于工作与生活,支持多场景应用。 • 功能:文本生成、

By Ne0inhk
一文带你掌握Visual Studio中集成的git功能

一文带你掌握Visual Studio中集成的git功能

前言 Visual Studio中深度集成了git功能,可以很方便的进行源代码版本控制功能。 大部分日常的操作我们可以通过界面来完成,这样就省去了输入git命令的时间,也可以不用记很多参数。 但这毕竟是辅助工具,掌握常用的git命令行还是很有必要的。 言归正传,接下来开始介绍Visual Studio 中集成的git功能。 本文以Visual Studio 2022为例进行演示 安装 Visual Studio的UI中已经集成了git相关功能,但是也需要安装git后才能使用。 如果没有安装git,在使用相关功能时,可能会看到如下的提示 安装方式可以通过以下两种 1、在Visual Studio的安装程序中,钩选<适用于Windows的Git> 推荐使用这种方式,因为免去了单独下载和安装的环节 2、访问git官方网站,下载安装包手动安装 下载地址:Git - Install for Windows 导入/克隆(clone)代码 方法1、在Visual Studio的启动界面上选择克隆存储库 输入

By Ne0inhk

llama.cpp量化模型部署实战:从模型转换到API服务

1. 为什么你需要关注llama.cpp:让大模型在普通电脑上跑起来 如果你对AI大模型感兴趣,肯定听说过动辄需要几十GB显存的“庞然大物”。想在自己的电脑上跑一个7B参数的模型,以前可能得配一张昂贵的专业显卡。但现在,情况不一样了。我今天要跟你聊的 llama.cpp,就是那个能让大模型“瘦身”并飞入寻常百姓家的神奇工具。 简单来说,llama.cpp是一个用C/C++编写的开源项目,它的核心目标只有一个:用最高效的方式,在消费级硬件(比如你的笔记本电脑CPU)上运行大型语言模型。它不像PyTorch那样是个庞大的深度学习框架,它更像一个“推理引擎”,专注于把训练好的模型,以最小的资源消耗跑起来。 我刚开始接触大模型部署时,也被各种复杂的依赖和巨大的资源需求劝退过。直到用了llama.cpp,我才发现,原来在我的MacBook Pro上,也能流畅地和Llama 2这样的模型对话。这背后的功臣,主要就是两点:纯C/C++实现带来的极致性能,以及模型量化技术带来的体积与速度革命。量化这个词听起来有点技术,你可以把它想象成给模型“压缩图片”

By Ne0inhk

Stable Yogi Leather-Dress-Collection开源可部署:SD1.5+Anything V5本地化部署全流程

Stable Yogi Leather-Dress-Collection开源可部署:SD1.5+Anything V5本地化部署全流程 想亲手打造一个能生成各种动漫风格皮衣穿搭的AI工具吗?今天,我们就来一步步部署一个名为“Stable Yogi Leather-Dress-Collection”的开源项目。它基于经典的Stable Diffusion 1.5模型和流行的Anything V5动漫风格模型,专门用来生成2.5D风格的皮衣穿搭图片。 这个工具最大的特点是“省心”。你不用再手动切换各种皮衣风格的模型文件,也不用费心去想复杂的提示词。它内置了智能管理功能,能自动识别你准备好的皮衣款式,并帮你生成匹配的绘图指令。更重要的是,它经过深度优化,对电脑显卡的要求比较友好,并且完全在本地运行,不需要联网,保护你的隐私。 无论你是想体验AI绘画的乐趣,还是想为角色设计寻找灵感,这个工具都是一个不错的起点。接下来,我将带你从零开始,完成整个环境的搭建和工具的启动。 1. 环境准备与项目部署 在开始生成酷炫的皮衣穿搭图之前,我们需要先把“画室”搭建好。这个过程主要分为两步:准备好

By Ne0inhk