16 条 yyds 的代码规范

作者 | 涛姐涛哥

链接 | cnblogs.com/taojietaoge/p/11575376.html

背景:如何更规范化编写Java 代码的重要性想必毋需多言,其中最重要的几点当属提高代码性能、使代码远离Bug、令代码更优雅。

 

一、MyBatis 不要为了多个查询条件而写 1 = 1

当遇到多个查询条件,使用where 1=1 可以很方便的解决我们的问题,但是这样很可能会造成非常大的性能损失,因为添加了 “where 1=1 ”的过滤条件之后,数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(即全表扫描) 以比较此行是否满足过滤条件,当表中的数据量较大时查询速度会非常慢;此外,还会存在SQL 注入的风险。

反例:

<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t where 1=1
<if test="title !=null and title !='' ">AND title = #{title} 
</if> 
<if test="author !=null and author !='' ">AND author = #{author}
</if> 
</select>

正例:

<select id="queryBookInfo" parameterType="com.tjt.platform.entity.BookInfo" resultType="java.lang.Integer">
select count(*) from t_rule_BookInfo t
<where>
<if test="title !=null and title !='' ">title = #{title} 
</if>
<if test="author !=null and author !='' "> AND author = #{author}
</if>
</where> 
</select>

UPDATE 操作也一样,可以用<set> 标记代替 1=1。

 

二、 迭代entrySet() 获取Map 的key 和value

当循环中只需要获取Map 的主键key时,迭代keySet() 是正确的;但是,当需要主键key 和取值value 时,迭代entrySet() 才是更高效的做法,其比先迭代keySet() 后再去通过get 取值性能更佳。

反例:

//Map 获取value 反例:
HashMap<String, String> map = new HashMap<>();
for (String key : map.keySet()){
String value = map.get(key);
}

正例:

  //Map 获取key & value 正例:
HashMap<String, String> map = new HashMap<>();for (Map.Entry<String,String> entry : map.entrySet()){String key = entry.getKey();String value = entry.getValue();
}

 

三、使用Collection.isEmpty() 检测空

使用Collection.size() 来检测是否为空在逻辑上没有问题,但是使用Collection.isEmpty() 使得代码更易读,并且可以获得更好的性能;除此之外,任何Collection.isEmpty() 实现的时间复杂度都是O(1) ,不需要多次循环遍历,但是某些通过Collection.size() 方法实现的时间复杂度可能是O(n)。O(1)纬度减少循环次数 例子

反例:

LinkedList<Object> collection = new LinkedList<>();
if (collection.size() == 0){System.out.println("collection is empty.");}

正例:

LinkedList<Object> collection = new LinkedList<>();
if (collection.isEmpty()){System.out.println("collection is empty.");}//检测是否为null 可以使用CollectionUtils.isEmpty()
if (CollectionUtils.isEmpty(collection)){System.out.println("collection is null.");}

 

四、初始化集合时尽量指定其大小

尽量在初始化时指定集合的大小,能有效减少集合的扩容次数,因为集合每次扩容的时间复杂度很可能时O(n),耗费时间和性能。

反例:

//初始化list,往list 中添加元素反例:int[] arr = new int[]{1,2,3,4};List<Integer> list = new ArrayList<>();for (int i : arr){list.add(i);}

正例:

//初始化list,往list 中添加元素正例:
int[] arr = new int[]{1,2,3,4};
//指定集合list 的容量大小List<Integer> list = new ArrayList<>(arr.length);
for (int i : arr){
list.add(i);}

 

五、使用StringBuilder 拼接字符串

一般的字符串拼接在编译期Java 会对其进行优化,但是在循环中字符串的拼接Java 编译期无法执行优化,所以需要使用StringBuilder 进行替换。

反例:

//在循环中拼接字符串反例String str = "";for (int i = 0; i < 10; i++){//在循环中字符串拼接Java 不会对其进行优化str += i;}

正例:

//在循环中拼接字符串正例
String str1 = "Love";
String str2 = "Courage";
String strConcat = str1 + str2;  //Java 编译器会对该普通模式的字符串拼接进行优化StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++){
//在循环中,Java 编译器无法进行优化,所以要手动使用StringBuildersb.append(i);}

 

 六、若需频繁调用Collection.contains 方法则使用Set

在Java 集合类库中,List的contains 方法普遍时间复杂度为O(n),若代码中需要频繁调用contains 方法查找数据则先将集合list 转换成HashSet 实现,将O(n) 的时间复杂度将为O(1)。

反例:

//频繁调用Collection.contains() 反例List<Object> list = new ArrayList<>();for (int i = 0; i <= Integer.MAX_VALUE; i++){//时间复杂度为O(n)if (list.contains(i))  System.out.println("list contains "+ i); }

正例:

//频繁调用Collection.contains() 正例List<Object> list = new ArrayList<>();Set<Object> set = new HashSet<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++){
//时间复杂度为O(1)
if (set.contains(i)){System.out.println("list contains "+ i);}}

 

七、使用静态代码块实现赋值静态成员变量

对于集合类型的静态成员变量,应该使用静态代码块赋值,而不是使用集合实现来赋值。

反例:

//赋值静态成员变量反例
private static Map<String, Integer> map = new HashMap<String, Integer>(){{
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);}};
private static List<String> list = new ArrayList<>(){{
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");}};

正例:

//赋值静态成员变量正例
private static Map<String, Integer> map = new HashMap<String, Integer>();
static {
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);}private static List<String> list = new ArrayList<>();
static {
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");}

八、删除未使用的局部变量、方法参数、私有方法、字段和多余的括号。

九、工具类中屏蔽构造函数

工具类是一堆静态字段和函数的集合,其不应该被实例化;但是,Java 为每个没有明确定义构造函数的类添加了一个隐式公有构造函数,为了避免不必要的实例化,应该显式定义私有构造函数来屏蔽这个隐式公有构造函数。

反例:

public class PasswordUtils {
//工具类构造函数反例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();}

正例:

public class PasswordUtils {
//工具类构造函数正例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);//定义私有构造函数来屏蔽这个隐式公有构造函数
private PasswordUtils(){}public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();}

 

十、删除多余的异常捕获并抛出

用catch 语句捕获异常后,若什么也不进行处理,就只是让异常重新抛出,这跟不捕获异常的效果一样,可以删除这块代码或添加别的处理。

反例:

//多余异常反例
private static String fileReader(String fileName)throws IOException{try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {builder.append(line);}
return builder.toString();} catch (Exception e) {
//仅仅是重复抛异常 未作任何处理
throw e;}
}

正例:

//多余异常正例
private static String fileReader(String fileName)throws IOException{try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {builder.append(line);}
return builder.toString();
//删除多余的抛异常,或增加其他处理:
/*catch (Exception e) {return "fileReader exception";}*/}
}

 

十一、字符串转化使用String.valueOf(value) 代替 " " + value

把其它对象或类型转化为字符串时,使用String.valueOf(value) 比 ""+value 的效率更高。

反例:

//把其它对象或类型转化为字符串反例:int num = 520;// "" + valueString strLove = "" + num;

正例:

//把其它对象或类型转化为字符串正例:int num = 520;// String.valueOf() 效率更高String strLove = String.valueOf(num);

 

十二、避免使用BigDecimal(double)

BigDecimal(double) 存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。

反例:

// BigDecimal 反例BigDecimal bigDecimal = new BigDecimal(0.11D);

正例:

// BigDecimal 正例
BigDecimal bigDecimal1 = bigDecimal.valueOf(0.11D);

图1. 失去精度

 

十三、返回空数组和集合而非 null

若程序运行返回null,需要调用方强制检测null,否则就会抛出空指针异常;返回空数组或空集合,有效地避免了调用方因为未检测null 而抛出空指针异常的情况,还可以删除调用方检测null 的语句使代码更简洁。

反例:

//返回null 反例
public static Result[] getResults() {
return null;
}public static List<Result> getResultList() {
return null;
}public static Map<String, Result> getResultMap() {
return null;
}

正例:

//返回空数组和空集正例
public static Result[] getResults() {
return new Result[0];
}public static List<Result> getResultList() {
return Collections.emptyList();
}public static Map<String, Result> getResultMap() {
return Collections.emptyMap();
}

 

十四、优先使用常量或确定值调用equals 方法

对象的equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals 方法。

反例:

 //调用 equals 方法反例private static boolean fileReader(String fileName)throws IOException{// 可能抛空指针异常return fileName.equals("Charming"); }

正例:

//调用 equals 方法正例
private static boolean fileReader(String fileName)throws IOException{// 使用常量或确定有值的对象来调用 equals 方法
return "Charming".equals(fileName);//或使用:java.util.Objects.equals() 方法
return Objects.equals("Charming",fileName);}

 

十五、枚举的属性字段必须是私有且不可变

枚举通常被当做常量使用,如果枚举中存在公共属性字段或设置字段方法,那么这些枚举常量的属性很容易被修改;理想情况下,枚举中的属性字段是私有的,并在私有构造函数中赋值,没有对应的Setter 方法,最好加上final 修饰符。

反例:

public enum SwitchStatus {
// 枚举的属性字段反例DISABLED(0, "禁用"),ENABLED(1, "启用");public int value;
private String description;private SwitchStatus(int value, String description) {
this.value = value;
this.description = description;}public String getDescription() {
return description;}public void setDescription(String description) {
this.description = description;}
}

正例:

public enum SwitchStatus {
// 枚举的属性字段正例DISABLED(0, "禁用"),ENABLED(1, "启用");// final 修饰
private final int value;
private final String description;private SwitchStatus(int value, String description) {
this.value = value;
this.description = description;}// 没有Setter 方法
public int getValue() {
return value;}public String getDescription() {
return description;}
}

 

十六、string.split(String regex)部分关键字需要转译

使用字符串String 的 split 方法时,传入的分隔字符串是正则表达式,则部分关键字(比如 .[]()\| 等)需要转义。

反例:

 // String.split(String regex) 反例String[] split = "a.ab.abc".split(".");System.out.println(Arrays.toString(split));   // 结果为[]String[] split1 = "a|ab|abc".split("|");System.out.println(Arrays.toString(split1));  // 结果为["a", "|", "a", "b", "|", "a", "b", "c"]

正例:

// String.split(String regex) 正例
// . 需要转译
String[] split2 = "a.ab.abc".split("\\.");
System.out.println(Arrays.toString(split2));  // 结果为["a", "ab", "abc"]// | 需要转译
String[] split3 = "a|ab|abc".split("\\|");
System.out.println(Arrays.toString(split3));  // 结果为["a", "ab", "abc"]

图2. String.split(String regex) 正反例

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

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

相关文章

linkedhashset_Java LinkedHashSet clear()方法与示例

linkedhashsetLinkedHashSet类的clear()方法 (LinkedHashSet Class clear() method) clear() method is available in java.util package. clear()方法在java.util包中可用。 clear() method is used to clear all of the existing objects in this LinkedHashSet. clear()方法…

C# 导出word文档及批量导出word文档(3)

在初始化WordHelper时&#xff0c;要获取模板的相对路径。获取文档的相对路径多个地方要用到&#xff0c;比如批量导出时要先保存文件到指定路径下&#xff0c;再压缩打包下载&#xff0c;所以专门写了个关于获取文档的相对路径的类。 1 #region 获取文档的相对路径2 pub…

Nginx For Windows 路由配置

Nginx For Windows 路由配置一、路由配置说明二、需求说明三、配置文件一、路由配置说明 使用Nginx进行路由配置。 使用过 SpringCloud 网关的同学都知道&#xff0c;网关可以使用同一IP地址、同一端口号、不同的服务ID&#xff0c;转发不同服务API信息&#xff0c;不会出现跨…

再见收费的 XShell,我改用国产良心工具!

使用或维护Linux系统的都知道&#xff0c;我们日常对服务器的操作&#xff0c;一般都会借助SSH工具远程登录到服务器之后进行操作。常用的SSH工具有不少&#xff0c;比如&#xff1a;Xshell、Putty、SSH Secure Shell Client、secureCRT等等。我使用过其中两种secureCRT和Xshel…

Java IdentityHashMap put()方法与示例

IdentityHashMap类的put()方法 (IdentityHashMap Class put() method) put() method is available in java.util package. put()方法在java.util包中可用。 put() method is used to set the given value element (val_ele) with the given key element (key_ele) when no valu…

全球六大国际域名解析量统计报告(6月25日)

IDC评述网&#xff08;idcps.com&#xff09;06月29日报道&#xff1a;根据DailyChanges公布的实时数据显示&#xff0c;在2015年6月25日&#xff0c;全球六大国际域名解析量总量持续攀升至153,246,819个&#xff0c;环比6月16日&#xff0c;净增46,078个&#xff0c;涨幅增大3…

Windows 创建符号链接

一、场景分析 1.环境变量 在Windows系统配置 环境变量 的时候&#xff0c;经常会遇到以下 路径 情况&#xff1a; C:\Program Files C:\Program Files (x86)\Common Files2.异常情况 这种路径中&#xff0c;存在空格字符&#xff0c;在一些程序调用时&#xff0c;可能出现异…

1.3w字,一文详解死锁!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone死锁&#xff08;Dead Lock&#xff09;指的是两个或两个以上的运算单元&#xff08;进程、线程或协程&#xff09;&#xff0c;都在等待…

Java Dictionary elements()方法与示例

字典类的elements()方法 (Dictionary Class elements() method) elements() method is available in java.util package. elements()方法在java.util包中可用。 elements() method is used to get the elements of an Enumeration in this dictionary. elements()方法用于获取此…

PHP与ThinkPHP读写文件

2019独角兽企业重金招聘Python工程师标准>>> 使用php将数据写入到指定的文件 $str"<?php return".var_export($phiz,true)."?>"; file_put_contents(./Data/phiz.php); 使用php读取指定的文件 …

软件版本号设置规则及示例

一、版本号设置规则 ABC客户端 版本说明书 [版本命名规则] 如&#xff1a;1.0.0.0 位数名称描述情景第一位主版本重大修改&#xff0c;重写或里程碑[里程碑] [重大更新]第二位次版本显著增强、功能变更较多[新增功能] [删减功能]第三位生成号功能变更&#xff0c;局部修正较多…

【图解】透彻Java线程状态转换

大家好&#xff0c;我是阿星&#xff0c;好久不见&#xff0c;欢迎来到Java并发编程系列番外篇线程状态转换&#xff0c;内容通俗易懂&#xff0c;请放心食用。线程状态先来个开场四连问Java线程状态有几个&#xff1f;Java线程状态是如何转换&#xff1f;Java线程状态转换什么…

Java Byte类的hashCode()方法及示例

短类hashCode()方法 (Short class hashCode() method) hashCode() method is available in java.lang package. hashCode()方法在java.lang包中可用。 hashCode() method is used to return hashcode of the Byte object. hashCode()方法用于返回Byte对象的哈希码。 hashCode()…

CentOS7安装Hadoop2.7完整流程

2019独角兽企业重金招聘Python工程师标准>>> 1、环境&#xff0c;3台CentOS7&#xff0c;64位&#xff0c;Hadoop2.7需要64位Linux&#xff0c;CentOS7 Minimal的ISO文件只有600M&#xff0c;操作系统十几分钟就可以安装完成&#xff0c; Master 192.168.0.182 Slav…

获取外网IP地址API

1、获取外网IP地址 地址&#xff1a; http://pv.sohu.com/cityjson?ieutf-8 返回结果&#xff1a; var returnCitySN {"cip": "39.***.***.***", "cid": "370000", "cname": "山东省"};2、获取IP地址详细信…

如果不这样用,Nacos也有安全问题!

前言配置管理作为软件开发中重要的一环&#xff0c;肩负着连接 代码和环境的职责&#xff0c;能很好的分离开发人员和维护人员的关注点。Nacos 的配置管理功能就很好地满足了云原生应用对于配置管理的需求&#xff1a;既能做到配置和代码分离&#xff0c;也能做到配置的动态…

java中intvalue_Java Byte类intValue()方法的示例

java中intvalue字节类intValue()方法 (Byte class intValue() method) intValue() method is available in java.lang package. intValue()方法在java.lang包中可用。 intValue() method is used to return the value denoted by this Byte object converted to type int (by c…

python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

python3.4学习笔记(八) Python第三方库安装与使用&#xff0c;包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般会看到以下几种格式的文件: msi, egg, whlmsi文件:Windows系统的安装包, 在Window…

Java BigDecimal toString()方法与示例

BigDecimal类toString()方法 (BigDecimal Class toString() method) toString() method is available in java.math package. toString()方法在java.math包中可用。 toString() method is used to represent string denotation of this BigDecimal with the help of scientific…

聊聊Spring事务失效的12种场景,太坑了

前言对于从事java开发工作的同学来说&#xff0c;spring的事务肯定再熟悉不过了。在某些业务场景下&#xff0c;如果一个请求中&#xff0c;需要同时写入多张表的数据。为了保证操作的原子性&#xff08;要么同时成功&#xff0c;要么同时失败&#xff09;&#xff0c;避免数据…