JAVA的16 个实用代码优化小技巧
一、类成员与方法的可见性最小化
举例:如果是一个private的方法,想删除就删除。
如果一个public的service方法,或者一个public的成员变量,删除一下,不得思考很多。
二、使用位移操作替代乘除法
计算机是使用二进制表示的,位移操作会极大地提高性能。
<< 左移相当于乘以 2;>> 右移相当于除以 2;
>>> 无符号右移相当于除以 2,但它会忽略符号位,空位都以 0 补齐。
a = val << 3;
b = val >> 1;
三、尽量减少对变量的重复计算
我们知道对方法的调用是有消耗的,包括创建栈帧、调用方法时保护现场,恢复现场等。
//反例
for (int i = 0; i < list.size(); i++) {System.out.println("result");
}//正例
for (int i = 0, length = list.size(); i < length; i++) {System.out.println("result");
}
在list.size()
很大的时候,就减少了很多的消耗。
四、不要捕捉RuntimeException
RuntimeException 不应该通过 catch 语句去捕捉,而应该使用编码手段进行规避。
如下面的代码,list 可能会出现数组越界异常。
是否越界是可以通过代码提前判断的,而不是等到发生异常时去捕捉。
提前判断这种方式,代码会更优雅,效率也更高。
public String test1(List<String> list, int index) {try {return list.get(index);} catch (IndexOutOfBoundsException ex) {return null;}
}//正例
public String test2(List<String> list, int index) {if (index >= list.size() || index < 0) {return null;}return list.get(index);
}
五、使用局部变量可避免在堆上分配
由于堆资源是多线程共享的,是垃圾回收器工作的主要区域,过多的对象会造成 GC 压力,可以通过局部变量的方式,将变量在栈上分配。这种方式变量会随着方法执行的完毕而销毁,能够减轻 GC 的压力。
六、减少变量的作用范围
注意变量的作用范围,尽量减少对象的创建。
如下面的代码,变量 s 每次进入方法都会创建,可以将它移动到 if 语句内部。
public void test(String str) {final int s = 100;if (!StringUtils.isEmpty(str)) {int result = s * s;}
}
七、尽量采用懒加载的策略,在需要的时候才创建
String str = "1";
if (name == "2") {list.add(str);
}if (name == "2") {String str = "1";list.add(str);
}
八、访问静态变量直接使用类名
使用对象访问静态变量,这种方式多了一步寻址操作,需要先找到变量对应的类,再找到类对应的变量。
// 反例
int i = objectA.staticMethod();// 正例
int i = ClassA.staticMethod();
九、字符串拼接使用StringBuilder
字符串拼接,使用 StringBuilder 或者 StringBuffer,不要使用 + 号。
//反例
public class StringTest {@Testpublic void testStringPlus() {String str = "111";str += "222";str += "333";System.out.println(str);}}//正例
public class TestMain {public static void main(String[] args) {StringBuilder sb = new StringBuilder("111");sb.append("222");sb.append(333);System.out.println(sb.toString());}
}
十、重写对象的HashCode,不要简单地返回固定值
有同学在开发重写 HashCode 和 Equals 方法时,会把 HashCode 的值返回固定的 0,而这样做是不恰当的
当这些对象存入 HashMap 时,性能就会非常低,因为 HashMap 是通过 HashCode 定位到 Hash 槽,有冲突的时候,才会使用链表或者红黑树组织节点,固定地返回 0,相当于把 Hash 寻址功能无效了。
十一、HashMap等集合初始化的时候,指定初始值大小
这样的对象有很多,比如 ArrayList,StringBuilder 等,通过指定初始值大小可减少扩容造成的性能损耗。
初始值大小计算可以参考《阿里巴巴开发手册》:
十二、循环内不要不断创建对象引用
//反例
for (int i = 1; i <= size; i++) {Object obj = new Object();
}//正例
Object obj = null;
for (int i = 0; i <= size; i++) {obj = new Object();
}
第一种会导致内存中有size个Object对象引用存在,size很大的话,就耗费内存了
十三、遍历Map 的时候,使用 EntrySet 方法
使用 EntrySet 方法,可以直接返回 set 对象,直接拿来用即可;而使用 KeySet 方法,获得的是key 的集合,需要再进行一次 get 操作,多了一个操作步骤,所以更推荐使用 EntrySet 方式遍历 Map。
Set<Map.Entry<String, String>> entryseSet = nmap.entrySet();
for (Map.Entry<String, String> entry : entryseSet) {System.out.println(entry.getKey()+","+entry.getValue());
}
十四、不要在多线程下使用同一个 Random
Random 类的 seed 会在并发访问的情况下发生竞争,造成性能降低,建议在多线程环境下使用 ThreadLocalRandom 类。
public static void main(String[] args) {ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();Thread thread1 = new Thread(()->{for (int i=0;i<10;i++){System.out.println("Thread1:"+threadLocalRandom.nextInt(10));}});Thread thread2 = new Thread(()->{for (int i=0;i<10;i++){System.out.println("Thread2:"+threadLocalRandom.nextInt(10));}});thread1.start();thread2.start();}
十五、自增推荐使用LongAddr
自增运算可以通过 synchronized 和 volatile 的组合来控制线程安全,或者也可以使用原子类(比如 AtomicLong)。
后者的速度比前者要高一些,AtomicLong 使用 CAS 进行比较替换,在线程多的情况下会造成过多无效自旋,可以使用 LongAdder 替换 AtomicLong 进行进一步的性能提升。
public class Test {public int longAdderTest(Blackhole blackhole) throws InterruptedException {LongAdder longAdder = new LongAdder();for (int i = 0; i < 1024; i++) {longAdder.add(1);}return longAdder.intValue();}
}
十六、程序中要少用反射
反射的功能很强大,但它是通过解析字节码实现的,性能就不是很理想。
现实中有很多对反射的优化方法,比如把反射执行的过程(比如 Method)缓存起来,使用复用来加快反射速度。
Java 7.0 之后,加入了新的包java.lang.invoke
,同时加入了新的 JVM 字节码指令 invokedynamic,用来支持从 JVM 层面,直接通过字符串对目标方法进行调用。
相关文章:

JAVA的16 个实用代码优化小技巧
一、类成员与方法的可见性最小化 举例:如果是一个private的方法,想删除就删除。 如果一个public的service方法,或者一个public的成员变量,删除一下,不得思考很多。 二、使用位移操作替代乘除法 计算机是使用二进制…...

并发编程的三大挑战之原子性及其解决方案
目录 一、原子性问题 1、带来原子性问题的原因 2、如何解决线程切换带来的原子问题 2.1、使用synchronized关键字来保证 2.2、使用CAS来保证原子性 2.3、使用lock锁来保证 一、原子性问题 1、带来原子性问题的原因 线程切换是带来原子的根本原因,java的并发程…...
QML动画(其他的动画)
PauseAnimation (暂停动画) 为动画提供暂停 Rectangle{id:rect1width: 100;height: 100;x:100;y:100color: "lightBlue"SequentialAnimation{running: trueColorAnimation {target: rect1;property: "color";…...

Spark 配置项
Spark 配置项硬件资源类CPU内存堆外内User Memory/Spark 可用内存Execution/Storage Memory磁盘ShuffleSpark SQLJoin 策略调整自动分区合并自动倾斜处理配置项分为 3 类: 硬件资源类 : 与 CPU、内存、磁盘有关的配置项Shuffle 类 : Shuffle 计算过程的配置项Spark SQL : Spar…...
掌握Vue3模板语法,助你轻松实现高效Web开发
Vue3作为前端开发中的一种主流框架,为我们提供了多种灵活的方式来处理模板语法。除了基础的模板语法,Vue3还提供了一些高级的语法,可以让我们更好地处理组件、响应式数据和UI逻辑等。在这篇博客中,我们将介绍Vue3中的一些高级模板…...

Jmeter+Ant+Jenkins接口自动化测试平台搭建
平台简介一个完整的接口自动化测试平台需要支持接口的自动执行,自动生成测试报告,以及持续集成。Jmeter支持接口的测试,Ant支持自动构建,而Jenkins支持持续集成,所以三者组合在一起可以构成一个功能完善的接口自动化测…...
ncnn部署(CMakelists.txt)
1. NCNN 环境安装 参考博客: 基于ncnn的yolov5模型部署 1. 1 protobuf编译 打开VS2013/VS2019的X64命令行(注意不是cmd),我这里以V32013环境进行编译 > cd <protobuf-root-dir> > mkdir build-vs2013 > cd build-vs2013 > cmake -G"NMake Makefil…...

SQL分库分表
什么是分库分表? 分库分表是两种操作,一种是分库,一种是分表。 分库分表又分为垂直拆分和水平拆分两种。 (1)分库:将原来存放在单个数据库中的数据,拆分到多个数据库中存放。 (2&…...

大数据分析案例-基于逻辑回归算法构建微博评论情感分类模型
🤵♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章 大数据分析案例合集…...
0105深度优先搜索算法非递归2种实现对比-无向图-数据结构和算法(Java)
1 两种非递归实现 在前面我们解决无向图的单点通性和单点路径问题时,都用到了深度优先搜索算法。深度优先搜索算法可以用递归和非递归两种方式。这里讨论非递归实现。 无向图结构使用邻接表实现。 第一种非递归方法(推荐),代码如…...

传统手工数据采集耗时耗力?Smartbi数据填报实现数据收集分析自动化
企业在日常经营管理过程中,往往需要收集很多内外部的信息,清洗整理后再进行存储、分析、呈现、决策支持等各种作业,如何高效收集结构化数据是企业管理者经常要面对的问题。传统手工的数据采集方式不仅耗费了大量人力时间成本,还容…...
《Spring源码深度分析》第5章 Bean的加载
目录标题前言一、Bean加载入口与源码分析1、Bean加载的入口2、Bean加载源码二、FactoryBean的使用三、缓存中获取单例bean(待补充)前言 经过前面的分析,我们终于结束了对XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索…...
华为OD机试真题Java实现【求最大数字】真题+解题思路+代码(20222023)
求最大数字 题目 给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。 如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533 请返回经过删…...

Java——异常机制
前言 随着对java的不断深入学习,在对语法以及编程思想有了一定的了解之后,在编程的过程中有可能会因为用户的输入不正确或者逻辑错误而出现异常或者错误,因此如何去捕捉与避免不应该出现的异常或者错误就变得十分重要。本文就介绍了java的异…...

【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(下)
系列文章目录 【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(上) 【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(中) 【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate…...

ESP32设备驱动-土壤湿度传感器驱动
土壤湿度传感器驱动 1、土壤湿度传感器介绍 土壤湿度传感器由两个探头组成,用于测量水的体积含量。 两个探头让电流通过土壤,然后得到电阻值来测量水分值。 当有更多的水时,土壤会传导更多的电,这意味着电阻会更小。 因此,水分含量会更高。 干燥的土壤导电性差,所以当…...

公网远程连接MongoDB数据库【内网穿透】
文章目录1. 安装数据库2. 内网穿透2.1 创建隧道映射2.2 测试随机公网地址远程连接3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供…...

SQL注入——floor报错注入
目录 一,涉及到的函数 rand() floor() concat_ws() as别名,group by分组 count() 报错原理 一,涉及到的函数 rand()函数:随机返回0~1间的小数 floor()函数:小数向…...
P6入门:在EPS下创建项目(P6Professional)
引言 在 Primavera P6 中,一旦创建了企业项目结构EPS,就可以开始向该结构添加项目。项目是一组活动和数据,它们构成了创建产品或服务的计划。项目有开始日期和结束日期,可以包括活动、资源、工作分解结构、组织分解结构、日历、关…...

Linux安装及管理应用和账号和权限管理 讲解
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...