Java常用类-比较器
目录
- 一、为什么需要比较器?
- 二、核心差异速记表
- 三、Comparable:对象自带的 “默认规则”
- 1. 核心作用
- 2. 源码定义
- 3. 实战:给Student类加默认规则
- 4. 源码验证(以Integer为例)
- 四、Comparator:临时的 “外部规则”
- 1. 核心作用
- 2. 源码定义
- 3. 实战:给 Student 加临时规则
- 方式 1:匿名内部类(传统写法)
- 方式 2:Lambda 表达式(Java 8+ 简化写法)
- 4. 源码验证(以 Arrays.sort 为例)
- 4.1 Arrays.sort()
- 4.1.1 无Comparator时
- 4.1.2 有 Comparator 时
- 4.2 TreeMap中的比较器优先级
- 五、Comparator 的进阶
- 1. 多条件排序(先按 A,再按 B)
- 2. 空值处理(允许 null)
- 3. 反转顺序
- 六、最佳实践总结
- 1.比较器三原则(违反会导致排序异常):
- 2.整数比较的陷阱
- 3.选择策略:
- 4.JDK8+高效写法:
- 七、记忆口诀(一句话记住核心)
- 1.Comparable:
- 2.Comparator:
- 3.优先级:
- 八、常见面试题
- 1.Comparable 和 Comparator 的区别?
- 2.如果一个类没有实现 Comparable,能否排序?
- 3.compareTo 和 compare 方法的返回值有什么要求?
- 4.如何对自定义对象排序?
- 5.Comparator 有哪些常用方法?
- 6.如何实现逆序排序?
- 7.比较器在HashMap中的作用?
一、为什么需要比较器?
场景:
- 对 Integer、String 等内置类型排序时,JDK 知道怎么比大小(如 1 < 2,“a” < “b”)。
- 但对自定义对象(如 User、Product),JDK 不知道按什么规则排序(按年龄?按价格?)。
比较器就是用来定义 “对象比较规则” 的工具。
二、核心差异速记表
Comparable(自然排序) | Comparator(定制排序) | |
---|---|---|
包位置 | java.lang | java.util |
接口方法 | compareTo(T o) | compare(T o1, T o2) |
使用场景 | 类本身的默认排序规则 | 临时定义多种排序策略 |
规则位置 | 写在类内部(实现接口) | 写在类外部(单独定义) |
修改代码 | 需要修改类源码 | 不修改原有类 |
排序方式 | 单一自然排序 | 支持多种排序规则 |
典型应用 | String、Integer等包装类的排序 | 第三方库排序,多条件排序 |
三、Comparable:对象自带的 “默认规则”
1. 核心作用
让对象 “自带” 一个比较规则,就像人天生知道 “年龄大的更年长” 一样。只要对象实现了Comparable,就能直接用Arrays.sort() 或Collections.sort() 排序。
2. 源码定义
// JDK 源码(java.lang.Comparable)
public interface Comparable<T> {int compareTo(T o); // 定义比较规则的方法
}
- 返回值含义(重点!):
- 如果 this < o → 返回负数(比如 -1)。
- 如果 this == o → 返回 0。
- 如果 this > o → 返回正数(比如 1)。
3. 实战:给Student类加默认规则
假设Student默认按分数升序排序:
public class Student implements Comparable<Student> {private String name;private int score;// 重写 compareTo:定义“分数升序”规则@Overridepublic int compareTo(Student other) {return this.score - other.score; // 分数小的排前面}// 构造方法、getter 省略...
}
使用示例:
Student[] students = {new Student("张三", 85),new Student("李四", 75),new Student("王五", 90)
};Arrays.sort(students); // 直接排序!因为 Student 实现了 Comparable
// 排序后顺序:李四(75)、张三(85)、王五(90)
4. 源码验证(以Integer为例)
Integer能直接排序,因为它实现了Comparable:
// JDK 源码(java.lang.Integer)
public final class Integer implements Comparable<Integer> {public int compareTo(Integer another) {return this.value - another.value; // 按数值大小比较}
}
四、Comparator:临时的 “外部规则”
1. 核心作用
当对象没有实现Comparable,或者需要临时改变排序规则(比如Student平时按分数排,但今天要按姓名排),就用Comparator。
2. 源码定义
// JDK 源码(java.util.Comparator)
@FunctionalInterface // 函数式接口(可 Lambda)
public interface Comparator<T> {int compare(T o1, T o2); // 定义比较规则的方法
}
- 返回值含义和 Comparable 一致:
- o1 < o2 → 负数;o1 == o2 → 0;o1 > o2 → 正数。**
3. 实战:给 Student 加临时规则
需求:Student平时按分数排(Comparable),但今天需要按姓名长度降序排。
方式 1:匿名内部类(传统写法)
// 定义一个“姓名长度降序”的比较器
Comparator<Student> nameLengthComparator = new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {// 姓名长度大的排前面(降序)return s2.getName().length() - s1.getName().length();}
};// 使用这个比较器排序
Arrays.sort(students, nameLengthComparator);
// 排序后顺序:张三(2字)、李四(2字)、王五(2字)→ 若长度相同,保持原顺序
方式 2:Lambda 表达式(Java 8+ 简化写法)
// 用 Lambda 简化 Comparator 定义
Comparator<Student> nameLengthComparator = (s1, s2) -> s2.getName().length() - s1.getName().length();Arrays.sort(students, nameLengthComparator); // 效果同上
4. 源码验证(以 Arrays.sort 为例)
4.1 Arrays.sort()
// 在TimSort(Java排序算法实现)中的关键代码
if (c.compare(a[runHi++], a[lo]) < 0) { // 使用比较器判断顺序// 执行元素交换等操作
}
Arrays.sort 有两种重载,分别对应 Comparable 和 Comparator:
4.1.1 无Comparator时
public static <T extends Comparable<? super T>> void sort(T[] a) {// 直接调用对象的compareTo方法TimSort.sort(a, 0, a.length, null, 0, 0);
}
约束:数组元素必须实现Comparable,否则报ClassCastException。
4.1.2 有 Comparator 时
public static <T> void sort(T[] a, Comparator<? super T> c) {// 使用传入的ComparatorTimSort.sort(a, 0, a.length, c, 0, 0);
}
灵活性:无需元素实现Comparable,临时传入规则即可。
4.2 TreeMap中的比较器优先级
public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator; // 比较器优先于自然排序
}final int compare(Object k1, Object k2) {return comparator==null ? ((Comparable)k1).compareTo(k2): comparator.compare(k1, k2);
}
五、Comparator 的进阶
1. 多条件排序(先按 A,再按 B)
需求:学生先按分数降序,分数相同则按姓名升序。
// 组合比较器:先按分数降序,分数相同按年龄升序
Comparator<Student> complexComparator = Comparator.comparingInt(Student::getScore).reversed() // 分数降序(先主条件).thenComparingInt(Student::getAge);// 分数相同,按姓名升序(次条件)Arrays.sort(students, multiComparator);// 相当于:
(s1, s2) -> {int scoreCompare = Integer.compare(s2.getScore(), s1.getScore());return (scoreCompare != 0) ? scoreCompare : Integer.compare(s1.getAge(), s2.getAge());
};
2. 空值处理(允许 null)
// null 排在最前面(nullsFirst)
Comparator<Student> nullsFirstComparator = Comparator.nullsFirst(Comparator.comparing(Student::getScore));// null 排在最后面(nullsLast)
Comparator<Student> nullsLastComparator = Comparator.nullsLast(Comparator.comparing(Student::getScore));
3. 反转顺序
Comparator<Student> scoreAsc = Comparator.comparingInt(Student::getScore); // 分数升序
Comparator<Student> scoreDesc = scoreAsc.reversed(); // 反转成降序
六、最佳实践总结
1.比较器三原则(违反会导致排序异常):
自反性:compare(a, a) == 0
对称性:compare(a, b) == -compare(b, a)
传递性:若compare(a, b) > 0且compare(b, c) > 0,则compare(a, c) > 0
2.整数比较的陷阱
// 错误写法(可能溢出):
return o1.id - o2.id;// 正确写法:
return Integer.compare(o1.id, o2.id);
3.选择策略:
- 类有自然顺序 → 实现Comparable
- 需要多种排序方式 → 使用Comparator
- 第三方类排序 → 必须用Comparator
4.JDK8+高效写法:
// 多字段排序
users.sort(Comparator.comparing(User::getLastName).thenComparing(User::getFirstName));// 按字符串长度排序
Comparator.comparing(String::length);
七、记忆口诀(一句话记住核心)
1.Comparable:
- 类内定义 “默认规则”,
- 所有排序都用它(如学生默认按分数);
- 例子:User implements Comparable,重写 compareTo。
2.Comparator:
- 类外定义 “临时规则”,
- 哪里需要哪里传(如学生临时按姓名);
- 例子:Collections.sort(users, (u1, u2) -> …)。
3.优先级:
当Comparable和Comparator同时存在时,Comparator优先(覆盖默认规则)。
八、常见面试题
1.Comparable 和 Comparator 的区别?
答:Comparable 是类内部实现的接口(compareTo),定义对象的默认排序规则;Comparator 是外部定义的接口(compare),用于临时修改排序规则。
2.如果一个类没有实现 Comparable,能否排序?
答:可以!通过 Comparator 传入临时规则(如 Arrays.sort(数组, 自定义Comparator))。
3.compareTo 和 compare 方法的返回值有什么要求?
答:必须满足:负数(前者小)、0(相等)、正数(前者大)。如果返回值逻辑错误,排序会乱。
4.如何对自定义对象排序?
答:两种方式:
① 让类实现Comparable接口,重写compareTo。
② 不修改类,创建Comparator并传给排序方法。
5.Comparator 有哪些常用方法?
答:reversed()(反转)、thenComparing()(多条件排序)、nullsFirst()/nullsLast()(空值处理)。
6.如何实现逆序排序?
// 方法1:反转比较结果
Comparator<Student> reversed = (s1, s2) -> s2.compareTo(s1);// 方法2:使用内置方法
Comparator.comparing(Student::getScore).reversed();
7.比较器在HashMap中的作用?
HashMap不依赖比较器,但TreeMap的排序依赖比较器
相关文章:
Java常用类-比较器
目录 一、为什么需要比较器?二、核心差异速记表三、Comparable:对象自带的 “默认规则”1. 核心作用2. 源码定义3. 实战:给Student类加默认规则4. 源码验证(以Integer为例) 四、Comparator:临时的 “外部规…...
【Linux系列】bash_profile 与 zshrc 的编辑与加载
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
【大模型】解决最新的Dify1.3.1版本 无法基于Ollama成功添加模型
本地搭建参考链接,但是版本不是最新的1.3.1 DeepSeek Dify :零成本搭建企业级本地私有化知识库保姆级教程 windows环境下部署。 查看模型添加,提示成功,但实际模型接口返回值为空,即看不到已添加的模型。 解决方法…...
6.空气质量检测和语音播报
目录 传感器 传感器分类 数字量传感器 模拟量传感器 电压型模拟量传感器 电流型模拟量传感器 接收不同数字电平信号 KQM6600 简介 获取数据手册 关注手册的内容 KQM660硬件层 编辑 KQM协议层 语音识别和语音播报模块 SU03T作用 SU03T简介编辑 SU03T硬件层 …...
LeetCode 热题 100 543. 二叉树的直径
LeetCode 热题 100 | 543. 二叉树的直径 大家好,今天我们来解决一道经典的二叉树问题——二叉树的直径。这道题在 LeetCode 上被标记为简单难度,要求计算给定二叉树的直径。 问题描述 给你一棵二叉树的根节点,返回该树的直径。二叉树的直径…...
D. Explorer Space(dfs+剪枝)
Problem - 1517D - Codeforces 题目大意:给你一个n行m列的矩阵,以及每个点上下左右相邻点的边权,求出每个点任意走k步后再回到当前这个点的最小路程,如果不能回到起始点则输出-1 思路:既然走k步后要回到起始点&#…...
# KVstorageBaseRaft-cpp 项目 RPC 模块源码学习
KVstorageBaseRaft-cpp 项目 RPC 模块源码学习 。 一、项目简介 KVstorageBaseRaft-cpp 是一个基于 Raft 一致性算法实现的分布式 KV 存储系统,采用 C 开发。项目的核心目标是帮助开发者理解 Raft 原理和分布式 KV 存储的基本实现。RPC 模块是分布式系统通信的关…...
QT6 源(93)篇三:阅读与注释共用体类 QVariant 及其源代码,本类支持比较运算符 ==、!=。
(9) 本类支持比较运算符 、! : 可见, QString 类型里可存储多个 unicode 字符,即使只存储一个 unicode 字符也不等于 QChar。 (10)本源代码来自于头文件 qvariant . h : #ifndef Q…...
Qt开发经验 --- 避坑指南(13)
文章目录 [toc]1 安装Qt creator后无法使用debug调试2 安装VS后之间安装自带的Windows SDK3 Qt配置ssl4 ubuntu编译linuxdeployqt 更多精彩内容👉内容导航 👈👉Qt开发经验 👈 1 安装Qt creator后无法使用debug调试 安装最新版本Q…...
go 通过汇编学习atomic原子操作原理
文章目录 概要一、原理1.1、案例1.2、关键汇编 二、LOCK汇编指令2.1、 LOCK2.2、 原理2.2.1、 缓存行2.2.2、 缓存一致性之MESI协议2.2.3、lock原理 三、x86缓存发展四、x86 DMA发展参考 概要 在并发操作下,对一个简单的aa2的操作都会出错,这是因为这样…...
LOJ 6346 线段树:关于时间 Solution
Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1,a2,⋯,an),另有一个存储三元组的列表 L L L. 有 m m m 个操作分两种: add ( l , r , k ) \operatorname{add}(l,r,k) add(l,r,k):将 ( l , r , …...
Python----神经网络(基于Alex Net的花卉分类项目)
一、基于Alex Net的花卉分类 1.1、项目背景 在当今快速发展的科技领域,计算机视觉已成为一个备受关注的研究方向。随着深度学习技术的不断进步,图像识别技术得到了显著提升,广泛应用于医疗、安防、自动驾驶等多个领域。其中,花卉…...
影刀RPA开发-魔法指令-玩转图片识别
聊聊天,就能生成指令! 1. 影刀RPA提取图片内容的方式 官方AI识别 集成的第三方识别指令 免费的识别指令 使用python自己编写识别代码,自己安装第三方库 import easyocr# 创建一个 EasyOCR 识别器,指定同时识别中文(简…...
从零开始开发纯血鸿蒙应用之XML解析
从零开始开发纯血鸿蒙应用 〇、前言一、鸿蒙SDK中的 XML API1、ohos.xml2、ohos.convertxml 三、XML 解析实践1、源数据结构2、定义映射关系3、定义接收对象4、获取文章信息 四、总结 〇、前言 在前后端的数据传输方面,论格式化形式,JSON格式自然是首选…...
运算放大器稳定性分析
我们常见的运放电路大多是在闭环状态。那么就必然遵循闭环控制系统的基本原理。闭环控制系统的核心是通过反馈来调节系统的输出,使其更接近期望值。 本文从闭环控制系统的角度,画出同相、反相差分电路的经典控制框图。有了控制框图就可以利用经典控制理论…...
python【扩展库】websockets
文章目录 介绍基础教程安装websockets接收与发送消息介绍 websockets基于python构建websocket服务、客户端的扩展库;官方文档;优点是正确性(严格测试,100%分支覆盖)、简单性(自管理连接)、健壮性、高性能(C扩展加速内存操作),双向通信;基于(python标准异步io框架)…...
leetcode 454. 4Sum II
题目描述 代码: class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int,int> table;int temp 0;for(auto n1:nums1){fo…...
MCP 传输层代码分析
MCP 传输层代码分析 MCP 整体架构说明 引用官方文档原文:Model Context Protocol (MCP) 构建在一个灵活且可扩展的架构上,使 LLM 应用和集成之间的无缝通信成为可能。具体架构细节可以参考文档(核心架构 - MCP 中文文档)。MCP 采…...
OBS studio 减少音频中的杂音(噪音)
1. 在混音器中关闭除 麦克风 之外的所有的音频输入设备 2.在滤镜中增加“噪声抑制”和“噪声门限”...
java的Stream流处理
Java Stream 流处理详解 Stream 是 Java 8 引入的一个强大的数据处理抽象,它允许你以声明式方式处理数据集合(类似于 SQL 语句),支持并行操作,提高了代码的可读性和处理效率。 一、Stream 的核心概念 1. 什么是 Str…...
Windows使用虚拟环境执行sh脚本
在代码文件夹git bash here echo ‘export PATH“/f/anaconda/Scripts:$PATH”’ >> ~/.bashrc echo ‘source /f/anaconda/etc/profile.d/conda.sh’ >> ~/.bashrc source ~/.bashrc conda路径确认 where conda conda activate mmt bash ./online.sh感谢gpt记录…...
Transformer Decoder-Only 算力FLOPs估计
FLOPs和FLOPS的区别 FLOPs (Floating Point Operations)是指模型或算法执行过程中总的浮点运算次数,单位是“次”FLOPS (Floating Point Operations Per Second)是指硬件设备(如 GPU 或 CPU)每…...
数字电子技术基础(五十七)——边沿触发器
目录 1 边沿触发器 1.1 边沿触发器简介 1.1.1 边沿触发器的电路结构 1.3 边沿触发的D触发器和JK触发器 1.3.1 边沿触发的D型触发器 1.3.2 边沿触发的JK触发器 1 边沿触发器 1.1 边沿触发器简介 对于时钟触发的触发器来说,始终都存在空翻的现象,抗…...
05.three官方示例+编辑器+AI快速学习three.js webgl - animation - skinning - ik
本实例主要讲解内容 这个Three.js示例展示了**反向运动学(Inverse Kinematics, IK)**在3D角色动画中的应用。通过加载一个角色模型,演示了如何使用IK技术实现自然的肢体运动控制,如手部抓取物体的动作。 核心技术包括: CCD反向运动学求解器…...
MYSQL数据库集群高可用和数据监控平台
项目环境 项目拓扑结构 软硬件环境清单 软硬件环境清单 软硬件环境清单 主机名IP硬件软件 master1 192.168.12.130 VIP:192.168.12.200 cpu:1颗2核 内 存:2GB HDD:20GB 网 络:NAT VmWare17 OpenEuler22.03 SP4 MySql8.0.3…...
《异常链机制详解:如何优雅地传递Java中的错误信息?》
大家好呀!👋 作为一名Java开发者,相信你一定见过各种奇奇怪怪的异常报错。但有没有遇到过这样的情况:明明只调用了一个方法,却看到异常信息像俄罗斯套娃一样一层层展开?🤔 这就是我们今天要讲的…...
MySQL 数据库集群部署、性能优化及高可用架构设计
MySQL 数据库集群部署、性能优化及高可用架构设计 集群部署方案 1. 主从复制架构 传统主从复制:配置一个主库(Master)和多个从库(Slave)GTID复制:基于全局事务标识符的复制,简化故障转移半同步复制:确保至少一个从库接收到数据…...
什么是深度神经网络
深度神经网络(DNN)详细介绍 1. 定义与核心原理 深度神经网络(Deep Neural Network, DNN)是一种具有多个隐藏层的人工神经网络模型,其核心在于通过层次化的非线性变换逐步提取输入数据的高层次抽象特征。与浅层神经网络相比,DNN的隐藏层数量通常超过三层,例如VGGNet、R…...
深入解析PyTorch中MultiheadAttention的隐藏参数add_bias_kv与add_zero_attn
关键背景 最近在学习pytorch中的源码尤其是nn.modules下算子的实现,针对activation.py下MultiheadAttention下有两个不常见的参数的使用比较有趣,因为时序领域很少使用这两个参数(add_bias_kv和add_zero_attn),但是其…...
最大化效率和性能:AKS 中节点池的强大功能
什么是节点池 在 Azure Kubernetes 服务 (AKS) 中,相同配置的节点会被分组到节点池中。这些节点池包含运行应用程序的底层虚拟机。创建 AKS 集群时,您需要定义初始节点数及其大小 (SKU)。随着应用程序需求的变化,您可能需要更改节点池的设置…...
用户态到内核态:Linux信号传递的九重门(一)
1. 信号的认识 1.1. 信号的特点 异步通知:信号是异步的,发送信号的进程无需等待接收进程的响应。预定义事件:每个信号对应一个预定义的事件(如终止、中断、段错误等)。 轻量级:信号不携带大量数据…...
c语言第一个小游戏:贪吃蛇小游戏01
hello啊大家好 今天我们用一个小游戏来增强我们的c语言! 那就是贪吃蛇 为什么要做一个贪吃蛇小游戏呢? 因为这个小游戏所涉及到的知识有c语言的指针、数组、链表、函数等等可以让我们通过这个游戏来巩固c语言,进一步认识c语言。 一.我们先…...
JAVA EE_网络原理_网络层
晨雾散尽,花影清晰。 ----------陳長生. ❀主页:陳長生.-CSDN博客❀ 📕上一篇:数据库Mysql_联…...
前端性能指标及优化策略——从加载、渲染和交互阶段分别解读详解并以Webpack+Vue项目为例进行解读
按照加载阶段、渲染阶段和交互阶段三个维度进行系统性阐述: 在现代 Web 开发中,性能不再是锦上添花,而是决定用户体验与业务成败的关键因素。为了全面监控与优化网页性能,我们可以将性能指标划分为加载阶段、渲染阶段、和交互阶段…...
Flink 系列之十五 - 高级概念 - 窗口
之前做过数据平台,对于实时数据采集,使用了Flink。现在想想,在数据开发平台中,Flink的身影几乎无处不在,由于之前是边用边学,总体有点混乱,借此空隙,整理一下Flink的内容,…...
控制台打印带格式内容
1. 场景 很多软件会在控制台打印带颜色和格式的文字,需要使用转义符实现这个功能。 2. 详细说明 2.1.转义符说明 样式开始:\033[参数1;参数2;参数3m 可以多个参数叠加,若同一类型的参数(如字体颜色)设置了多个&…...
Linux为啥会重新设置中断请求号与中断向量号之间的关系?
Linux内核重新设置中断请求号(IRQ)与中断向量号之间的关系,主要出于以下核心原因和设计考量: 1. 硬件多样性与抽象需求 硬件中断号(HW Interrupt ID)的差异 不同处理器架构的中断控制器(…...
自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例
自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例 目录 自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例一、连续词袋( Cont…...
计算机网络笔记(二十二)——4.4网际控制报文协议ICMP
4.4.1ICMP报文的种类 ICMP(Internet Control Message Protocol)是IP协议的辅助协议,主要用于传递控制消息、错误报告和诊断信息。其报文分为两大类:查询报文和错误报告报文。 1. 错误报告报文(Error Messages&#x…...
【AI论文】作为评判者的感知代理:评估大型语言模型中的高阶社会认知
摘要:评估大型语言模型(LLM)对人类的理解程度,而不仅仅是文本,仍然是一个开放的挑战。 为了弥合这一差距,我们引入了Sentient Agent作为评判者(SAGE),这是一个自动评估框…...
Kubernetes生产实战(二十七):精准追踪Pod数据存储位置
在生产环境中,快速定位Pod数据的物理存储位置是运维人员的基本功。本文将揭秘Kubernetes存储系统的核心原理,并提供一套经过实战检验的定位方法体系。 一、存储架构全景图 K8S存储架构 Pod --> Volume Mount --> PVC --> PV --> Storage P…...
极新携手火山引擎,共探AI时代生态共建的破局点与增长引擎
在生成式AI与行业大模型的双重驱动下,人工智能正以前所未有的速度重构互联网产业生态。从内容创作、用户交互到商业决策,AI技术渗透至产品研发、运营的全链条,推动效率跃升与创新模式变革。然而,面对AI技术迭代的爆发期࿰…...
[SIGPIPE 错误] 一个 Linux socket 程序,没有任何报错打印直接退出程序
1. 问题 在编写一个程序的时候,当然程序很复杂,遇到了一个 Linux socket 程序,没有任何报错打印直接退出程序,但是在程序里面我有很多 error log ,在程序退出的时候完全没有打印。为了说明问题,我编写了一…...
Qt 界面优化(绘图)
目录 1. 绘图基本概念2. 绘制各种形状2.1 绘制线段2.2 绘制矩形2.3 绘制圆形2.4 绘制文本2.5 设置画笔2.6 设置画刷 3. 绘制图片3.1 绘制简单图片3.2 平移图片3.3 缩放图片3.4 旋转图片 4. 其他设置4.1 移动画家位置4.2 保存/加载画家的状态 5. 特殊的绘图设备5.1 QPixmap5.2 Q…...
AQS(AbstractQueuedSynchronizer)解析
文章目录 一、AQS简介二、核心设计思想2.1 核心设计思想回顾2.2 CLH锁队列简介2.3 AQS对CLH队列的改动及其原因 三、核心组件详解3.1 state 状态变量3.2 同步队列 (FIFO双向链表) 四、核心方法深度解析4.1 获取同步状态 (独占模式) - acquire(int arg)4.2 释放同步状态 (独占模…...
Java并发编程常见问题与陷阱解析
引言 随着计算机硬件技术的飞速发展,多核处理器已经变得普遍,Java并发编程的重要性也日益凸显。然而,多线程编程并非易事,其中充满了许多潜在的问题和陷阱。作为一名Java开发工程师,掌握并发编程的常见问题及其解决方案…...
DEEPPOLAR:通过深度学习发明非线性大核极坐标码(1)
原文:《DEEPPOLAR: Inventing Nonlinear Large-Kernel Polar Codes via Deep Learning》 摘要 信道编码设计的进步是由人类的创造力推动的,而且恰如其分地说,这种进步是零星的。极性码是在Arikan极化核的基础上开发的,代表了编码…...
Java多态详解
Java多态详解 什么是多态? 比如我们说:“驾驶一辆车”,有人开的是自行车,有人开的是摩托车,有人开的是汽车。虽然我们都说“开车”,但“怎么开”是由具体的车类型决定的:“开”是统一的动作&a…...
go程序编译成动态库,使用c进行调用
以下是使用 Go 语言打包成 .so 库并使用 C 语言调用的完整步骤: 1. Go 语言打包成 .so 库 (1)编写 Go 代码 创建一个 Go 文件(如 calculator.go),并定义需要导出的函数。导出的函数名必须以大写字母开头…...
iVX:图形化编程与组件化的强强联合
在数字化浪潮中,软件开发范式正经历着从文本到图形的革命性转变。iVX 作为国产可视化编程领域的领军者,以 “图形化逻辑 组件化架构” 的双重创新,重新定义了软件开发的效率边界。其技术突破不仅体现在开发方式的革新,更通过一系…...