JAVA中如何实现代码优化

news/2024/4/30 9:47:46/文章来源:https://blog.csdn.net/m0_59278919/article/details/127115585

 1.用String.format拼接字符串

 例:比如现在有个需求:要用get请求调用第三方接口,url后需要拼接多个参数。

       1) 以前我们的请求地址是这样拼接的:字符串使用+号拼接,非常容易出错。

String url = "http://susan.sc.cn?userName="+userName+"&age="+age+"&address="+address+"&sex="+sex+"&roledId="+roleId;

       2) 改为使用StringBuilder拼接字符串:代码优化之后,稍微直观点,但是看起来比较别扭。

StringBuilder urlBuilder = new StringBuilder("http://susan.sc.cn?");
urlBuilder.append("userName=")
.append(userName)
.append("&age=")
.append(age)
.append("&address=")
.append(address)
.append("&sex=")
.append(sex)
.append("&roledId=")
.append(roledId);

        3)使用String.format方法优化:代码的可读性,提升了很多。

String requestUrl = "http://susan.sc.cn?userName=%s&age=%s&address=%s&sex=%s&roledId=%s";
String url = String.format(requestUrl,userName,age,address,sex,roledId);

注意:我们平常可以使用String.format方法拼接url请求参数,日志打印等字符串。

           但不建议在for循环中用它拼接字符串,因为它的执行效率,比使用+号拼接字符串,或者使用StringBuilder拼接字符串都要慢一些。

2、创建可缓冲的IO流

IO流想必大家都使用得比较多,我们经常需要把数据写入某个文件,或者从某个文件中读取数据到内存中,甚至还有可能把文件a,从目录b,复制到目录c下等.

例:

public class IoTest1 {public static void main(String[] args) {FileInputStream fis = null;FileOutputStream fos = null;try {File srcFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/1.txt");File destFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/2.txt");fis = new FileInputStream(srcFile);fos = new FileOutputStream(destFile);int len;while ((len = fis.read()) != -1) {fos.write(len);}fos.flush();} catch (IOException e) {e.printStackTrace();} finally {try {if (fos != null) {fos.close();}} catch (IOException e) {e.printStackTrace();}try {if (fis != null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}
}

        这个例子主要的功能,是将1.txt文件中的内容复制到2.txt文件中。这例子使用普通的IO流从功能的角度来说,也能满足需求,但性能却不太好。因为这个例子中,从1.txt文件中读一个字节的数据,就会马上写入2.txt文件中,需要非常频繁的读写文件。

优化:

public class IoTest {public static void main(String[] args) {BufferedInputStream bis = null;BufferedOutputStream bos = null;FileInputStream fis = null;FileOutputStream fos = null;try {File srcFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/1.txt");File destFile = new File("/Users/dv_susan/Documents/workspace/jump/src/main/java/com/sue/jump/service/test1/2.txt");fis = new FileInputStream(srcFile);fos = new FileOutputStream(destFile);bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);byte[] buffer = new byte[1024];int len;while ((len = bis.read(buffer)) != -1) {bos.write(buffer, 0, len);}bos.flush();} catch (IOException e) {e.printStackTrace();} finally {try {if (bos != null) {bos.close();}if (fos != null) {fos.close();}} catch (IOException e) {e.printStackTrace();}try {if (bis != null) {bis.close();}if (fis != null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}
}

        这个例子使用BufferedInputStreamBufferedOutputStream创建了可缓冲的输入输出流。最关键的地方是定义了一个buffer字节数组,把从1.txt文件中读取的数据临时保存起来,后面再把该buffer字节数组的数据,一次性批量写入到2.txt中。

        这样做的好处是,减少了读写文件的次数,而我们都知道读写文件是非常耗时的操作。也就是说使用可缓存的输入输出流,可以提升IO的性能,特别是遇到文件非常大时,效率会得到显著提升。

3、减少循环次数

        在我们日常开发中,循环遍历集合是必不可少的操作。但如果循环层级比较深,循环中套循环,可能会影响代码的执行效率。

反例:

for(User user: userList) {for(Role role: roleList) {if(user.getRoleId().equals(role.getId())) {user.setRoleName(role.getName());}}
}

        这个例子中有两层循环,如果userList和roleList数据比较多的话,需要循环遍历很多次,才能获取我们所需要的数据,非常消耗cpu资源。

优化:

Map<Long, List<Role>> roleMap = roleList.stream().collect(Collectors.groupingBy(Role::getId));
for (User user : userList) {List<Role> roles = roleMap.get(user.getRoleId());if(CollectionUtils.isNotEmpty(roles)) {user.setRoleName(roles.get(0).getName());}
}

        减少循环次数,最简单的办法是,把第二层循环的集合变成map,这样可以直接通过key,获取想要的value数据。虽说map的key存在hash冲突的情况,但遍历存放数据的链表或者红黑树时间复杂度,比遍历整个list集合要小很多。

4、用完资源记得及时关闭

        在我们日常开发中,可能经常访问资源,比如:获取数据库连接,读取文件等。

反例

//1. 加载驱动类
Class.forName("com.mysql.jdbc.Driver");
//2. 创建连接
Connection connection = DriverManager.getConnection("jdbc:mysql//localhost:3306/db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8","root","123456");
//3.编写sql
String sql ="select * from user";
//4.创建PreparedStatement
PreparedStatement pstmt = conn.prepareStatement(sql);
//5.获取查询结果
ResultSet rs = pstmt.execteQuery();
while(rs.next()){int id = rs.getInt("id");String name = rs.getString("name");
}

       上面这段代码可以正常运行,但却犯了一个很大的错误,即:ResultSet、PreparedStatement和Connection对象的资源,使用完之后,没有关闭。数据库连接是非常宝贵的资源。我们不可能一直创建连接,并且用完之后,也不回收,白白浪费数据库资源。

正例:

//1. 加载驱动类
Class.forName("com.mysql.jdbc.Driver");Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {//2. 创建连接connection = DriverManager.getConnection("jdbc:mysql//localhost:3306/db?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8","root","123456");//3.编写sqlString sql ="select * from user";//4.创建PreparedStatementpstmt = conn.prepareStatement(sql);//5.获取查询结果rs = pstmt.execteQuery();while(rs.next()){int id = rs.getInt("id");String name = rs.getString("name");}
} catch(Exception e) {log.error(e.getMessage(),e);
} finally {if(rs != null) {rs.close();}if(pstmt != null) {pstmt.close();}if(connection != null) {connection.close();}
}

         这个例子中,无论是ResultSet,或者PreparedStatement,还是Connection对象,使用完之后,都会调用close方法关闭资源。

        ResultSet,或者PreparedStatement,还是Connection对象,这三者关闭资源的顺序不能反了,不然可能会出现异常。

 5、使用池技术

我们都知道,从数据库查数据,首先要连接数据库,获取Connection资源。

想让程序多线程执行,需要使用Thread类创建线程,线程也是一种资源。

通常一次数据库操作的过程是这样的:

  1. 创建连接

  2. 进行数据库操作

  3. 关闭连接

        而创建连接和关闭连接,是非常耗时的操作,创建连接需要同时会创建一些资源,关闭连接时,需要回收那些资源。 

缺点:

1)如果用户的每一次数据库请求,程序都都需要去创建连接和关闭连接的话,可能会浪费大量的时间。

2)可能会导致数据库连接过多。

这时我们可以使用数据库连接池,目前Java开源的数据库连接池有:

1)DBCP:是一个依赖Jakarta commons-pool对象池机制的数据库连接池。

2)C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

3)Druid:阿里的Druid,不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。

4)Proxool:是一个Java SQL Driver驱动程序,它提供了对选择的其它类型的驱动程序的连接池封装,可以非常简单的移植到已有代码中。

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

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

相关文章

Linux安全之SELinux理解

安全增强式 Linux&#xff0c;即SELinux(Security-Enhanced Linux)是一个 Linux 内核的安全模块&#xff0c;其提供了访问控制安全策略机制&#xff0c;包括了强制访问控制(Mandatory Access Control&#xff0c;MAC)。SELinux 是一组内核修改和用户空间工具&#xff0c;已经被…

0052-Tui-设置方块样式

环境Time 2022-08-09 Rust 1.62.0 Tui 0.18.0前言 说明 参考:https://github.com/fdehau/tui-rs/blob/master/examples/block.rs 目标 使用 tui-rs 对方块设置各种不同的样式。 设置背景色 let block = widgets::Block::default().title("设置背景色").style(style:…

跨境电商如何利用WhatsApp API交互式按钮提高客户转化率

WhatsApp API有很多实用的功能&#xff0c;跨境电商卖家因此可以为客户提供出色的客户服务体验与服务。 跨境电商卖家在通过WhatsApp API为客户提供服务或进行营销时&#xff0c;交互性功能可以明显提高客户转化率。因为当用户想要选择服务或产品时&#xff0c;可以直接使用交…

Java / Tensorflow - API 调用 pb 模型使用 GPU 推理

目录 一.引言 二.Java / Tensorflow 代码配置 1.代码配置 2.Maven 配置 三.环境检测 1.显卡检测 2.显卡监控 四.推理踩坑 1.异常现象 2.异常日志 五.安装 cuda-10.0 1.下载 cuda 安装包 2.安装 cuda 2.1 preface 前言 2.2 安装配置 2.3 安装完成 2.4 可能遇到的…

day013--mysql中的子查询

目录 一&#xff0c;前言 二&#xff0c;子查询的定义及书写格式 1&#xff0c;定义 2&#xff0c;书写格式 三&#xff0c;子查询的分类 1&#xff0c;单行子查询和多行子查询 2&#xff0c;相关子查询和非相关子查询 一&#xff0c;前言 相信大家还记得之前我们在学习分…

保研专业课参考

文章目录数据结构1.什么是平衡树&#xff1f;平衡树是怎么创建的&#xff1f;2.二叉排序树的性质&#xff1a;3.如何编程判断一棵二叉树是完全二叉树4.二叉树怎么求高度&#xff08;山大计算机&#xff09;5.在图中找到一个连通图&#xff0c;有n个顶点&#xff0c;n-1条边使得…

SQL Server大分区表没有空分区的情况下如何扩展分区的方法

官方文档https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-partition-function-transact-sql?viewsql-server-ver16 Best Practices Always keep empty partitions at both ends of the partition range. Keep the partitions at both ends to guarantee that th…

【学生网页作业】航海王动漫网页 html+ css + JavaScript 简单的学生网页作业源码

&#x1f329;️ 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f482; 作者主页: 【进入主页—&#x1f680;获取更多源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;HTML5网页期末作业 (1000套…

手机用Postern配置socks5全局代理详细教程

以静态Socks5独享IP的单地区资源为例&#xff0c;即IP资源全部归属单一城市&#xff0c;不会变动&#xff0c;如南京区域&#xff0c;则IP全部为南京城市出口。 关于Socks5的使用有多种方案&#xff0c;可应用于PC&#xff0c;安卓&#xff0c;模拟器&#xff0c;请根据情况灵…

EasyRecovery15万能数据恢复软件全面详细功能讲解

EasyRecovery 15是由全球著名数据厂商Ontrack 出品的一款非常优秀的数据恢复软件&#xff0c;在诸多数据恢复软件中这款软件可以说是排的上名的&#xff0c;具有快捷、高效、便捷等特点&#xff0c;可以帮助用户轻松恢复电脑丢失的数据。 因此今天coco玛吉多就给大家带来了eas…

环境主题静态HTML网页作业作品 大学生环保网页设计制作成品 简单DIV CSS布局网站

&#x1f329;️ 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f482; 作者主页: 【进入主页—&#x1f680;获取更多源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;HTML5网页期末作业 (1000套…

2022短视频神器历时6个月辛苦全力打造的软件短视频运用工具

短视频批量监控混剪消重上传运营神器 ​ 要问当下什么最火&#xff1f;当然是从事自媒体了&#xff0c;自媒体是普通大众经由数字科技强化、与全球知识体系相连之后&#xff0c;一种开始理解普通大众如何提供与分享他们自身的事实、新闻的途径。简而言之&#xff0c;即公民用以…

移动端布局

移动端布局1. meta视口标签1.2 多倍图1.2.1 图片缩放1.2.2 背景缩放 background-size1.3 特殊样式2 移动端常见布局2.1 流式布局&#xff08;百分比布局&#xff09;2.2 flex布局父项常见属性2.2.1 flex-direction设置主轴或侧轴的方向2.2.2 justify-content 设置主轴的子元素的…

程序员的数学课08 加乘法则:如何计算复杂事件发生的概率?

在我们的工作和生活中少不了对概率的计算&#xff0c;对概率的准确计算会帮助我们做出更加合理高效的决策。 例如&#xff0c;早上出门之前&#xff0c;你需要对是否携带雨伞进行决策。如果没有任何依据而随机决策&#xff0c;那么就会遇到下雨没带伞或者晴天带伞的麻烦&#…

SiO2/PAA/Ag复合纳米粒/酞菁修饰磁性温敏二氧化硅纳米微球/中空SiO2/TiO2纳米微球的制备

小编给大家分享了SiO2/PAA/Ag复合纳米粒/酞菁修饰磁性温敏二氧化硅纳米微球/中空SiO2/TiO2纳米微球的制备与研究&#xff0c;一起来看&#xff01; SiO2/PAA/Ag复合纳米粒子的制备步骤&#xff1a; 利用溶胶-凝胶法合成胶体二氧化硅微球,用甲基丙烯酰氧丙基三甲氧基硅烷(γ-MP…

业务开发流程

0.摘要 此文主要介绍了业务开发的整体流程、关键节点和需要注意的事项&#xff0c;适用于刚入行的小白&#xff0c;以及对自己过往经验的一个总结整理。持续更新中~~ 1.开发的主要流程&名词释义 大概给大家梳理下一个项目从发起到上线的流程。 ○ 参与人员&#xff1a;业…

redis之为什么那么快

写在前面 在面试中关于redis经常被问到一个问题就是redis为什么快&#xff0c;本文就一起从其底层的数据结构实现来分析下&#xff0c;为什么快&#xff0c;哪些快&#xff0c;哪些慢&#xff0c;哪些操作会导致慢等&#xff0c;下面我们就开始吧&#xff01; 1&#xff1a;为…

【无标题】近几年攻防演练攻击队典型突破的例子

蓝队经典攻击实例 实战攻防演练中红队网络的部署情况各有特点&#xff0c;蓝队也会根据攻 击目标的不同而采取不同的攻击策略和手段。下面几个案例展示的就 是针对红队网络的不同薄弱点采取的不同的典型攻击策略与方法手 段。 正面突破&#xff1a;跨网段控制工控设备 某企业…

C#面向对象程序设计课程实验一:实验名称:C#语言基础、程序流程控制

C#面向对象程序设计课程实验一&#xff1a;实验名称&#xff1a;C#语言基础、程序流程控制实验内容&#xff1a;C#语言基础、程序流程控制一、 实验目的二、实验环境三、实验内容四、实验总结实验内容&#xff1a;C#语言基础、程序流程控制 一、 实验目的 (1)练习 C#变量声明和…

simulink-自定义模块GUI回调函数

目录 一、创建simulink模块 二、自定义GUI步骤 2.1 设计组件界面信息 2.2 GUI控件介绍 2.2.1 Parameter参数配置组件 2.2.2 Container参数配置组件 2.2.3 Display参数配置组件 2.2.4 Action参数配置组件 2.3 控件回调函数使用方法 三、设置Help信息 四、获取配置控件参数 4.…