Java 黑马程序员学习笔记(进阶篇6)

常用的 API

1. 正则表达式

(1) 题目:贪婪爬取和非贪婪爬取

① 贪婪爬取:爬取数据的时候尽可能的多获取数据
② 非贪婪爬取:爬取数据的时候尽可能的少获取数据
③ Java中默认的是贪婪爬取
④ + 后面加上 ? 可以转变为非贪婪爬取

(2) 捕获分组

捕获分组通过 (...)将部分正则表达式包裹,会保存该组的匹配结果;后续可通过 \\nn为分组编号,从1开始)反向引用这组结果,实现 “重复使用已匹配的内容”。

需求 1:单字符首尾一致(如 a123ab456b

正则表达式(. ).+\\1

① 逻辑分解:

  • (. ):第1个捕获组,匹配任意一个字符.匹配任意字符,括号捕获该字符)。
  • .+:匹配中间任意长度的字符(1个或多个)。
  • \\1:反向引用第1个捕获组的内容,要求结尾字符必须和开头捕获的单个字符一致

② 示例验证:

  • a123a → 开头捕获a,结尾a → 匹配成功。
  • a123b → 开头a,结尾b → 匹配失败。
需求 2:多字符首尾一致(如 abc123abc&|@abc&|@

正则表达式(.+).+\\1

① 逻辑分解:

  • (.+):第1个捕获组,+表示 “1个或多个字符”,即匹配任意长度的开头子串(至少1个字符)。
  • .+:匹配中间任意长度字符。
  • \\1:反向引用第1个捕获组的内容,要求结尾子串必须和开头捕获的多字符子串完全一致

② 示例验证:

  • abc123abc → 开头捕获abc,结尾abc → 匹配成功。
  • abc123abd → 开头abc,结尾abd → 匹配失败。
需求 3 :首尾多字符(内部字符一致),且中间至少有 1 个字符,且开头内部至少重复 1 次

正则表达式((.)\\2+).+\\1

① 最内层:(.)(第 2 个捕获组)
  • (.)( 表示创建捕获组,. 匹配任意单个字符(比如 ab& 等)。
  • 这部分的作用:捕获一个 “基础字符”,后续会重复使用这个字符。
  • 编号:因为是第 2 个出现的左括号(第一个左括号是外层的 (),所以是第 2 组,后续用 \\2 引用。
② 中间层:\\2+
  • \\2:反向引用第 2 组捕获的 “基础字符”(比如第 2 组捕获了 a\\2 就代表 a)。
  • +:量词,表示 “至少出现 1 次”(和 * 不同,* 允许 0 次,+ 必须 1 次及以上)。
  • 组合起来:\\2+ 表示 “基础字符至少重复 1 次”(比如基础字符是 a,就匹配 aaaaaaaaa 等)。
③ 外层分组:((.)\\2+)(第 1 个捕获组)
  • 把 (.) 和 \\2+ 整体包裹,形成第 1 组。
  • 作用:捕获 “由同一个基础字符重复组成的子串”,且这个子串长度至少 2 个字符(因为基础字符 1 个 + 至少重复 1 次 = 2 个及以上)。
    例如:
    • 基础字符 a + \\2+a 重复 2 次)→ 第 1 组捕获 aaa
    • 基础字符 & + \\2+& 重复 1 次)→ 第 1 组捕获 &&
④ 中间内容:.+
  • . 匹配任意字符,+ 表示 “至少 1 次”。
  • 作用:要求开头和结尾的子串之间,必须有至少 1 个字符(不能是空的)。
⑤ 结尾:\\1
  • 反向引用第 1 组捕获的内容(即 “由同一个基础字符重复组成的子串”)。
  • 作用:要求字符串结尾的子串,必须和开头的子串完全一致
需求 4:“口吃” 字符去重

将包含重复字符的字符串(如 我要学学编编编编编程程程程程程),替换为单个重复字符,最终得到 我要学编编程

public class RegexDemo4 {public static void main(String[] args) {// 原始字符串:包含重复的“学”“编”“程”String str = "我要学学编编编编编程程程程程程";// 正则:匹配“单个字符 + 至少1个相同重复字符”String regex = "(.)\\1+";// 替换:用“基准字符($1)”替换“重复字符组”String result = str.replaceAll(regex, "$1");System.out.println(result); // 输出:我要学编编程}
}

关键逻辑 1:拆解 (.)\\1+

① 处理 “学学”

  • (.) 捕获第一个 “学”(组 1 存 “学”);
  • \\1+ 匹配第二个 “学”(满足 “至少 1 次”);
  • 匹配到 “学学”,替换成 “$1”(即 “学”)。

② 处理 “编编编”

  • (.) 捕获第一个 “编”(组 1 存 “编”);
  • \\1+ 匹配后面的 “编编”(至少 1 次);
  • 匹配到 “编编编”,替换成 “编”

③ 处理 “程”

  • 因为 “程” 没有重复(\\1+ 要求至少 1 次重复,不满足),所以不匹配正则,保留原样。

④ 最终结果就是 “学编程”

关键逻辑 2:$1 的作用

$1 是正则表达式替换操作中的反向引用语法,用于在「替换字符串」中,引用正则里第一个捕获组(由圆括号 () 包裹的部分)所匹配到的具体内容

② 核心作用:在字符串替换时,用「捕获组匹配到的内容」替换「整个正则匹配到的重复 / 复杂内容」,实现 “提取关键部分,简化重复内容” 的效果。

③ 举例理解:

比如要把字符串 "aaaabbbcc" 中连续重复的字符压缩成单个

(1) 正则表达式:(.)\\1+

  • (.) 是第一个捕获组,负责 “捕获单个任意字符”(比如匹配 "aaaa" 时,捕获组会抓到 'a');
  • \\1+ 表示 “必须跟着至少一个和捕获组内容相同的字符”(即重复的 'a')。

(2) 替换字符串:"$1"
当正则匹配到 "aaaa" 时,$1 会引用第一个捕获组抓到的 'a',于是用 'a' 替换整个 "aaaa";同理,"bbb" 会被 'b' 替换,"cc" 会被 'c' 替换。

(3) 最终效果:"aaaabbbcc" → "abc"

关键总结:
  • (.):抓一个 “基准字符” 并记住(存到组 1);
  • \\1+:找 “和基准字符相同的、至少 1 个的后续字符”,凑成 “重复序列”;
  • replaceAll(..., "$1"):用 “基准字符” 替换整个 “重复序列”,实现 “去重”。

2. Date

JDK 8 之前的时间处理:在 Java 8 之前,日期和时间的处理主要依赖 DateSimpleDateFormatCalendar 三个核心类(但存在可操作性弱、线程不安全等局限性,因此 JDK 8 后被新的 java.time 包替代)。

java.util.Date 类

package demo2;import java.util.Date;
import java.util.Random;public class test4 {public static void main(String[] args) {Random r = new Random();Date d1 = new Date(Math.abs(r.nextInt()));Date d2 = new Date(Math.abs(r.nextInt()));long time1 = d1.getTime();long time2 = d2.getTime();if (time1 > time2) {System.out.println("第一个时间在前面,第二个时间在后面");} else if (time1 < time2) {System.out.println("第二个时间在前面,第二个时间在后面");} else {System.out.println("两个时间一样");}}
关键逻辑 1:Date d1 = new Date(参数);

Date 类的本质是 “封装一个具体的时间点”,而它最核心的构造函数就是 Date(long date)—— 接收一个 long 类型的数字(称为 “时间戳”),并以此创建对应的时间对象。

② 时间戳的定义:指 从 1970 年 1 月 1 日 00:00:00 GMT(格林威治标准时间)开始,到某个时间点的 “毫秒数”
比如:

  • 时间戳 0 → 对应 1970-01-01 00:00:00 GMT;
  • 时间戳 1000 → 对应 1970-01-01 00:00:01 GMT(比基准时间多 1 秒,1 秒 = 1000 毫秒);
  • 时间戳越大,代表的时间越靠后(越 “新”)。
  • 代码中 new Date(参数) 的作用:
    用传入的 “时间戳” 创建一个 Date 对象,这个对象就代表了该时间戳对应的 “具体时间点”。
    比如 d1 就是一个封装了 “参数对应时间戳” 的时间对象,d2 同理。

关键逻辑 2:long time1 = d1.getTime();

Date 类的 getTime() 方法是上述构造函数的 反向操作

② 作用:返回当前 Date 对象所封装的 时间戳(毫秒数)
简单说:

  • 用 new Date(时间戳) 可以把 “数字” 变成 “时间对象”;
  • 用 getTime() 可以把 “时间对象” 变回 “数字(时间戳)”。

SimpleDateFormat 类

① 核心作用:实现 Date(日期对象) 与 String(字符串) 的双向转换:

  • 格式化:将 Date 转换为自定义格式的字符串
  • 解析:将自定义格式的字符串转换为 Date

② 构造方法

构造方法说明
public SimpleDateFormat()创建对象,使用默认日期格式
public SimpleDateFormat(String pattern)创建对象,使用指定的格式模板(如 yyyy-MM-dd

③ 常用方法

方法说明转换方向
public final String format(Date date)将 Date 格式化为字符串Date → String
public Date parse(String source)将字符串解析为 DateString → Date

④ 常用符号

符号含义示例(日期 2000-11-11
yyyyy → 2000
MMM → 11
ddd → 11
H时(24 小时制)HH → 00(假设为 0 点)
mmm → 00
sss → 00
⑤ 练习:秒杀活动时间范围校验程序

题目描述:某平台开展限时秒杀活动,活动时间为 2023年11月11日 0:0:0 至 2023年11月11日 0:10:0。请编写程序,判断某笔订单的时间(2023年11月11日 0:01:00)是否在秒杀活动的有效时间范围内,若在范围内则提示 “参加秒杀活动成功”,否则提示 “参加秒杀活动失败”。

package demo2;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class test8 {public static void main(String[] args) throws ParseException {String startStr = "2023年11月11日 0:0:0";String endStr = "2023年11月11日 0:10:0";String orderStr = "2023年11月11日 0:01:00";SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");Date startDate = sdf.parse(startStr);Date endDate = sdf.parse(endStr);Date orderDate = sdf.parse(orderStr);long startTime = startDate.getTime();long endTime = endDate.getTime();long orderTime = orderDate.getTime();if (orderTime >= startTime && orderTime <= endTime) {System.out.println("参加秒杀活动成功");} else {System.out.println("参加秒杀活动失败");}}
}

Calendar 类

① 概论

  • Calendar 是代表系统当前时间的日历对象,可单独修改、获取 “年、月、日、时、分、秒” 等时间字段。
  • 关键细节:Calendar 是抽象类不能直接通过 new 创建对象,需通过静态方法获取实例。

② 获取 Calendar 实例的方法

通过静态方法 getInstance() 获取 “当前系统时间” 的日历对象:

Calendar cal = Calendar.getInstance();

③ 常用方法及功能

方法签名说明
public final Date getTime()将 Calendar 转换为 Date 对象(用于和旧版 Date 类交互)。
public final void setTime(Date date)将 Date 对象设置到 Calendar 中(反向交互)。
public long getTimeInMillis()获取当前 Calendar 对应的时间戳(毫秒数)(从 1970-01-01 00:00:00 GMT 起算)。
public void setTimeInMillis(long millis)通过 ** 时间戳(毫秒数)** 设置 Calendar 的时间。
public int get(int field)获取日历中指定字段的值(需配合 Calendar 常量,如 Calendar.YEAR)。
public void set(int field, int value)修改日历中指定字段的值(如设置年份为 2025)。
public void add(int field, int amount)为日历中指定字段“增加 / 减少” 指定值(如月份 + 1、天数 - 3)。
④ 常用字段常量(配合 get/set/add 使用)

Calendar 定义了常量表示 “年、月、日” 等字段,常用的有:

  • Calendar.YEAR:年
  • Calendar.MONTH:月(注意:月份从 0 开始,0=1 月,11=12 月
  • Calendar.DAY_OF_MONTH:月中的日期
  • Calendar.HOUR_OF_DAY:24 小时制的 “时”
  • Calendar.MINUTE:分
  • Calendar.SECOND:秒

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

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

相关文章

计算机网络---数据链路层上

文章目录1. 数据链路层的功能2. 组帧2.1 字符填充法2.2 字节填充法2.3 零比特填充法2.4 违规编码2.5 总结3. 差错控制3.1 检错编码3.1.1 奇偶校验3.1.2 循环冗余校验码&#xff08;CRC&#xff09;3.1.3 总结3.2 纠错编码&#xff08;海明校验码&#xff09;3.3 总结4. 流量控制…

机器学习实战项目中,回归与分类模型中该如何科学定义目标变量Y?

前言 在机器学习项目里&#xff0c;目标变量 (Y) 的定义决定了你能解答什么问题&#xff0c;以及模型能给业务带来什么价值。选择不当不仅可能导致模型误差大、偏差严重&#xff0c;还可能让业务决策方向偏离。 本文分两大场景&#xff1a; 供应链项目中的 销量预测&#xff08…

【 C/C++ 算法】入门动态规划-----一维动态规划基础(以练代学式)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是动态规划算法的基础入门篇&#xff0c;我将通过三道简单题 一道中等难度的一维动态规划题来带你对动态规划有个初认识&#xff0c;并基本了解动…

深入对比Tomcat与Netty:HTTP请求从网卡到Controller的全链路追踪

我们日常用Spring Boot写的RestController&#xff0c;感觉上就是一个简单的方法&#xff0c;但它背后其实有一套复杂的网络服务在支撑。一个HTTP请求到底是怎么从用户的浏览器&#xff0c;穿过层层网络&#xff0c;最终抵达我们代码里的Controller方法的&#xff1f;理解这个过…

GO学习记录十——发包

记录下不同平台的发包操作和期间遇到的问题 1.命令&#xff1a; $env:GOOSlinux $env:GOARCHamd64 go build -o release/HTTPServices-linux第一行&#xff0c;配置平台&#xff0c;linux、windows 第二行&#xff0c;配置部署服务器的处理器架构 第三行&#xff0c;输出目标文…

贪心算法与动态规划

1. 什么是贪心算法&#xff1f; 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。 核心思想&#xff1a;“每步都贪心地选择眼前最好的&#xff0c;不去考虑整个未来的长…

学会“读网页”:生成式 AI 在足球赛事信息整理中的实战

逐步教程&#xff08;Step-by-Step&#xff09; — 适合初学者与教学类文章 背景&#xff08;为什么要这样做&#xff09; 对于足球迷、资讯编辑与数据分析师来说&#xff0c;最快、最准确把握一场比赛的核心信息至关重要&#xff1a;比分、关键事件&#xff08;进球、点球、红…

BM3D 图像降噪快速算法的 MATLAB 实现

BM3D 图像降噪快速算法的 MATLAB 实现1. 快速 BM3D 算法流程&#xff08;概述&#xff09;步骤操作加速技巧① 分组块匹配 堆叠FFT 互相关② 协同滤波3D 变换 硬阈值FFT 沿第三维③ 聚合加权平均稀疏矩阵累加 2. 核心函数&#xff08;单文件版&#xff09; 保存为 bm3d_fast.…

Go的schedt调度(runtime/proc.go)

1. 创建go的入口函数// Create a new g running fn. // Put it on the queue of gs waiting to run. // The compiler turns a go statement into a call to this. func newproc(fn *funcval) {gp : getg()pc : sys.GetCallerPC()systemstack(func() {newg : newproc1(fn, gp, …

Ubuntu 服务器配置转发网络访问

配置文档&#xff1a;Ubuntu 服务器转发网络访问 一、网络拓扑以以下网络拓扑为示例Ubuntu 服务器&#xff08;两个网卡&#xff09; eth1 10.66.71.222 &#xff08;接入内网&#xff09;eno1 192.168.2.100 &#xff08;直连相机&#xff09; 相机ip 192.168.2.1 Windows 客…

为什么企业需要高防IP

1. 抵御日益猖獗的DDoS攻击 现代DDoS攻击规模已突破Tbps级别 传统防火墙无法应对大规模流量攻击 高防IP采用分布式清洗中心&#xff0c;可轻松抵御300Gbps以上的攻击流量 2. 保障业务连续性 网络中断1小时可能造成数百万损失 高防IP确保服务99.99%可用性 智能切换机制实…

CSS基础 - 选择器备忘录 --笔记5

目录基础选择器组合器伪类选择器属性选择器选择器可以选中页面上的特定元素并为其指定样式。 CSS有多种选择器。 基础选择器 标签选择器 – tagname&#xff1a;匹配目标元素的标签名。优先级是0,0,1。如&#xff1a;p、h1、div类选择器 – .class&#xff1a;匹配class属性中…

自动驾驶中的传感器技术46——Radar(7)

卫星雷达&#xff08;又称为分布式雷达&#xff09;主要讲当前雷达的雷达信号处理计算以及雷达目标相关的一些感知算法都迁移到中央域控进行&#xff0c;雷达端基本只负责数据采集&#xff0c;这样做的影响如下&#xff1a; 雷达端成本与功耗降低&#xff1b; 雷达端采样得到的…

【论文阅读】Diff-Privacy: Diffusion-based Face Privacy Protection

基于扩散模型的人脸隐私保护方法——DiffPrivacy&#xff0c;解决了两类人脸隐私任务&#xff1a;匿名化&#xff08;anonymization&#xff09;和视觉身份信息隐藏&#xff08;visual identity information hiding&#xff09;。1. 研究背景随着人工智能和大数据技术的普及&am…

React 原理篇 - 深入理解虚拟 DOM

一、什么是虚拟 DOM&#xff1f; 在前端开发中&#xff0c;“虚拟 DOM” 是一个高频出现的术语&#xff0c;尤其在 React 生态中被广泛讨论。但很多开发者对它的理解往往停留在 “JS 对象” 这个表层认知上。 实际上&#xff0c;虚拟 DOM 是一种编程概念—— 在这个概念里&…

对汇编的初理解

此处是一个简单的函数&#xff0c;里面将调用了一个函数add&#xff08;&#xff09;函数这里是函数的原型这里是调用lcd函数产生的汇编语言&#xff0c;翻译过来就是r11&#xff0c;r0cnt(r4cnt,前文有提及)&#xff0c;然后调用add函数&#xff0c;此处BL是指会回到指令的下一…

《Python 自动化实战:从零构建一个文件同步工具》

《Python 自动化实战:从零构建一个文件同步工具》 一、开篇引入:为什么我们需要文件同步? 你是否有过这样的困扰: 公司电脑和家里电脑上都有工作项目,每次更新都要手动复制? U 盘频繁传输文件,不仅麻烦还容易出错? 项目文件夹动辄几 G,每次同步都耗时长、效率低? 在…

工业相机与镜头的靶面尺寸详解:选型避坑指南

在机器视觉系统中&#xff0c;相机与镜头的靶面尺寸匹配是一个非常关键却又经常被忽略的细节。选错了&#xff0c;不但影响图像质量&#xff0c;还可能导致画面“黑角”、视野不符、镜头浪费等问题。 今天我们就用通俗易懂的方式&#xff0c;聊一聊相机与镜头靶面尺寸的那些事儿…

使用 Go 和 go-commons 实现内存指标采集并对接 Prometheus

文章目录一、准备工作二、编写内存采集代码三、运行 Exporter四、接入 Prometheus五、可扩展思路总结在运维和监控领域&#xff0c;资源指标采集 是必不可少的一环。CPU、内存、磁盘、网络这些系统资源&#xff0c;需要实时采集并上报到监控系统中。 本文以 内存指标采集 为例&…

webrtc弱网-IntervalBudget类源码分析与算法原理

一、核心功能 IntervalBudget 类用于基于时间窗口的带宽预算管理。它根据设定的目标比特率&#xff08;kbps&#xff09;和一个固定时间窗口&#xff08;500ms&#xff09;&#xff0c;计算在该时间窗口内可用的字节数&#xff08;即“预算”&#xff09;&#xff0c;并支持预…