1.让代码更高效1.1.当需要Map的主键和值时,应该迭代entrySet()当循环中只需要Map的主键时,迭代keySet()是正确的。但是,当需要主键和值时,迭代entrySet()效率更高,比先迭代keySet()再获取值要好。反例:Mapma??p=...;for(Stringkey:map.keySet()){Stringvalue=map.get(key);...}正例:Mapma??p=...;for(Map.Entryentry:map.entrySet()){Stringkey=entry.getKey();Stringvalue=entry.getValue();...}1.2。Collection.isEmpty()检测是否为空使用Collection.size()检测是否为空没有逻辑问题,但使用Collection.isEmpty()可使代码更具可读性并可以获得更好的性能。任何Collection.isEmpty()实现都具有O(1)时间复杂度,但某些Collection.size()实现可能具有O(n)时间复杂度。反例:if(collection.size()==0){...}正例:if(collection.isEmpty()){...}如果需要检查null,可以使用CollectionUtils.isEmpty(collection)和CollectionUtils。isNotEmpty(集合)。1.3.不要将集合对象传递给自己将集合作为参数传递给集合自己的方法要么是错误的,要么是无意义的代码。此外,由于某些方法要求参数在执行期间保持不变,因此将集合传递给自身可能会导致意外行为。反例:Listlist=newArrayList<>();list.add("Hello");list.add("World");if(list.containsAll(list)){//无意义,总是返回true...}list.removeAll(list);//性能差,直接用clear()1.4.集合初始化尽量指定大小Java集合类用起来很方便,但是看源码,集合也是有大小限制的。每次展开的时间复杂度很可能是O(n),所以尽量指定一个可预测的集合大小来减少集合展开的次数。反例:int[]arr=newint[]{1,2,3};Listlist=newArrayList<>();for(inti:arr){list.add(i);}正例:int[]arr=newint[]{1,2,3};Listlist=newArrayList<>(arr.length);for(inti:arr){list.add(i);}1.5。字符串拼接的使用一般StringBuilder的字符串拼接在java编译时都会优化,但是循环中的字符串拼接在java编译时无法优化,所以需要使用StringBuilder进行替换。反例:Strings="";for(inti=0;i<10;i++){s+=i;}正例:Stringa="a";Stringb="b";Stringc="c";Strings=a+b+c;//没问题,java编译器会优化StringBuildersb=newStringBuilder();for(inti=0;i<10;i++){sb.append(i);//循环中,java编译器不能为了优化,需要手动使用StringBuilder}1.6。随机访问List大家都知道数组和链表的区别:随机访问数组效率更高。调用获取List的方法后,如果想随机访问其中的数据,不知道数组内部实现是链表还是数组怎么办?可以判断是否实现了RandomAccess接口。正例://调用别人的服务获取listListlist=otherService.getList();if(listinstanceofRandomAccess){//内部数组实现,随机访问System.out.println(list.get(list.size()-1));}else{//内部可能是链表实现,随机访问效率低}1.7.频繁调用Collection.contains方法,请使用Set在java集合类库中,List的contains方法一般时间复杂度为O(n),如果代码中需要频繁调用contains方法查找数据,你可以先把list转成HashSet,把时间复杂度从O(n)降到O(1)。反例:ArrayListlist=otherService.getList();for(inti=0;i<=Integer.MAX_VALUE;i++){//时间复杂度O(n)list.contains(i);}正例:ArrayListlist=otherService.getList();Setset=newHashSet(list);for(inti=0;i<=Integer.MAX_VALUE;i++){//时间复杂度O(1)set。contains(i);}2.让代码更优雅2.1.在长整数常量后添加一个大写的L。当使用长整型常量值时,需要在其后加L。必须是大写的L,不能是小写的l,小写的l很容易和数字1混淆,造成误会。反例:longvalue=1l;longmax=Math.max(1L,5);正例:longvalue=1L;longmax=Math.max(1L,5L);2.2.不要使用魔法值当你写一段代码时,使用魔法值可能看起来没有歧义,但在调试时它们并没有显得那么明确。这就是为什么需要将魔法值定义为可读常量。但是,-1、0和1不被视为魔法值。反例:for(inti=0;i<100;i++){...}if(a==100){...}正例:privatestaticfinalintMAX_COUNT=100;for(inti=0;imap=newHashMap(){{put("a",1);put("b",2);}};privatestaticListlist=newArrayList(){{add("a");add("b");}};正例:privatestaticMapmap=newHashMap<>();static{map.put("a",1);map.put("b",2);};privatestaticListlist=newArrayList<>();static{list.add("a");list.add("b");};2.4.推荐使用try-with-resources语句Java7引入try-with-resources语句,可以保证相关资源被关闭,比原来的try-catch-finally语句要好,让程序代码更安全、更简洁。反例:privatevoidhandle(StringfileName){BufferedReaderreader=null;try{Stringline;reader=newBufferedReader(newFileReader(fileName));while((line=reader.readLine())!=null){...}}catch(Exceptione){...}finally{if(reader!=null){try{reader.close();}catch(IOExceptione){...}}}}正例:privatevoidhandle(StringfileName){try(BufferedReaderreader=newBufferedReader(newFileReader(fileName))){Stringline;while((line=reader.readLine())!=null){...}}catch(Exceptione){...}}2.5。DeleteunusedprivatemethodsandfieldsRemoveunusedprivatemethodsandfields使代码更干净,更易于维护。如果需要再次使用,可以从历史提交中取回。反例:publicclassDoubleDemo1{privateintunusedField=100;privatevoidunusedMethod(){...}publicintsum(inta,intb){returna+b;}}正例:publicclassDoubleDemo1{publicintsum(inta,intb){returna+b;}}2.6.DeleteUnusedlocalvariables删除不用的局部变量,使代码更简洁,更易维护。反例:publicintsum(inta,intb){intc=100;returna+b;}正例:publicintsum(inta,intb){returna+b;}2.7.DeleteunusedmethodparametersUnusedmethodparametersaremisising,Removeunusedmethodparameters使代码更简洁和可维护。但是,由于覆盖方法是基于父类或接口的方法定义,所以即使有未使用的方法参数,也不能删除。反例:publicintsum(inta,intb,intc){returna+b;}正例:publicintsum(inta,intb){returna+b;}对代码阅读有帮助,也有人认为完全没有必要。对于熟悉Java语法的人来说,表达式中多出的括号会使代码更加繁琐。反例:return(x);return(x+2);intx=(y*3)+1;intm=(n*4+2);正例:returnx;returnx+2;intx=y*3+1;intm=n*4+2;2.9。工具类应该屏蔽构造函数。工具类是静态字段和函数的集合,不应实例化。然而,Java为每个没有显式定义构造函数的类添加了一个隐式公共构造函数。因此,为了避免java“小白”的错误使用,应该显式定义一个private构造函数来屏蔽这个隐含的public构造函数。反例:publicclassMathUtils{publicstaticfinaldoublePI=3.1415926D;publicstaticintsum(inta,intb){returna+b;}}正例:publicclassMathUtils{publicstaticfinaldoublePI=3.1415926D;privateMathUtils(){}publicstaticintsum(inta,intb){}2.10.删除多余的异常捕获和抛出。用catch语句捕获异常后,什么都不做,让异常再次抛出。这和不捕获异常的效果是一样的。您可以删除这段代码或添加其他处理。反例:privatestaticStringreadFile(StringfileName)throwsIOException{try(BufferedReaderreader=newBufferedReader(newFileReader(fileName))){Stringline;StringBuilderbuilder=newStringBuilder();while((line=reader.readLine())!=null){builder.append(line);}returnbuilder.toString();}catch(Exceptione){throwe;}}正例:privatestaticStringreadFile(StringfileName)throwsIOException{try(BufferedReaderreader=newBufferedReader(newFileReader(fileName))){Stringline;StringBuilderbuilder=newStringBuilder();while((line=reader.readLine())!=null){builder.append(line);}returnbuilder.toString();}}2.11。公共静态常量应该通过类来访问,虽然通过类实例访问公共静态常量是允许的,但是很容易让人误以为类的每个实例都有一个公共静态常量。因此,应该通过类直接访问公共静态常量。反例:publicclassUser{publicstaticfinalStringCONST_NAME="name";...}Useruser=newUser();StringnameKey=user.CONST_NAME;正例:publicclassUser{publicstaticfinalStringCONST_NAME="name";...}StringnameKey=User.CONST_NAME;2.12.DonotUseNullPointerExceptiontojudgednullandnullpointerexceptionshouldbevoidedbycode(例如检查它是否不为空),而不是通过捕获异常。反例:publicStringgetUserName(Useruser){try{returnuser.getName();}catch(NullPointerExceptione){returnnull;}}正例:publicStringgetUserName(Useruser){if(Objects.isNull(user)){returnnull;}returnuser.getName();}2.13。使用String.valueOf(value)而不是""+value将其他对象或类型转换为字符串时,使用String.valueOf(value)比""+value更高效。反例:inti=1;Strings=""+i;正例:inti=1;Strings=String.valueOf(i);2.14.为过时代码添加@Deprecated注解当一段代码已经过时,但为了兼容又不能直接删除,当你不想以后有人使用它时,可以添加@Deprecated注解来标记。在文档注释中添加@deprecated来解释并提供一个替代的正例:/***Save**@deprecated这种方法效率较低,请将其替换为{@linknewSave()}方法*/@Deprecatedpublicvoidsave(){//dosomething}3.使代码远离错误3.1。禁止使用构造函数BigDecimal(double)BigDecimal(double)存在精度丢失的风险,在精确计算或取值比较场景下可能会导致业务逻辑异常。反例:BigDecimalvalue=newBigDecimal(0.1D);//0.100000000000000005551115...正例:BigDecimalvalue=BigDecimal.valueOf(0.1D);//0.13.2。返回空数组和空集合而不是null返回null,需要调用side强制检测null,否则会抛出空指针异常。返回一个空数组或集合,有效防止调用者因为调用者没有检测到null而抛出空指针异常,也可以删除调用者检测到null的语句,让代码更简洁。反例:publicstaticResult[]getResults(){returnnull;}publicstaticListgetResultList(){returnull;}publicstaticMapgetResultMap(){returnnull;}publicstaticvoidmain(String[]args){Result[]results=getResults();if(results!=null){for(Resultresult:results){...}}ListresultList=getResultList();if(resultList!=null){for(Resultresult:resultList){...}}MapresultMap=getResultMap();if(resultMap!=null){for(Map.EntryresultEntry:resultMap){...}}}正例:publicstaticResult[]getResults(){returnnewResult[0];}publicstaticListgetResultList(){returnCollections.emptyList();}publicstaticMapgetResultMap(){returnCollections.emptyMap();}publicstaticvoidmain(String[]args){结果[]results=getResults();for(Resultresult:results){...}ListresultList=getResultList();for(Resultresult:resultList){...}MapresultMap=getResultMap();for(地图.EntryresultEntry:resultMap){...}}3.3。优先使用常量或确定值来调用equals方法。对象的equals方法很容易抛出空指针异常。应使用具有确定值的常量或对象来调用equals方法,当然最好使用java.util.Objects.equals()方法。反例:publicvoidisFinished(OrderStatusstatus){returnstatus.equals(OrderStatus.FINISHED);//可能抛出空指针异常}正例:publicvoidisFinished(OrderStatusstatus){returnOrderStatus.FINISHED.equals(status);}publicvoidisFinished(OrderStatusstatus){返回对象。(状态,OrderStatus.FINISHED);}3.4。枚举的属性字段必须是私有且不可变的。枚举通常用作常量。如果枚举中有公共属性字段或者设置字段方法,那么这些枚举常量的属性是很容易被修改的。理想情况下,枚举中的属性字段是私有的,在私有构造函数中赋值,没有对应的Setter方法,最好带final修饰符。反例:publicenumUserStatus{DISABLED(0,"Disabled"),ENABLED(1,"Enable");publicintvalue;privateStringdescription;privateUserStatus(intvalue,Stringdescription){this.value=value;this.description=description;}publicStringgetDescription(){returndescription;}publicvoidsetDescription(Stringdescription){this.description=description;}}正例:publicenumUserStatus{DISABLED(0,"Disabled"),ENABLED(1,"Enable");privatefinalintvalue;privatefinalStringdescription;privateUserStatus(intvalue,Stringdescription){this.value=value;this.description=description;}publicintgetValue(){returnvalue;}publicStringgetDescription(){returndescription;}}3.5。注意String.split(Stringregex)String字符串的split方法,传入的分隔符字符串是正则表达式!部分关键字(如.[]()\|等)需要进行转义反例:"a.ab.abc".split(".");//结果为[]"a|ab|abc".split("|");//结果为["a","|","a","b","|","a","b","c"]正例:“a.ab.abc”t;.split("\\.");//结果为["a","ab","abc"]"a|ab|abc".split("\\|");//resultis["a","ab","abc"]【小编推荐】5分钟让你理解K8S必备架构和网络模型的概念。1992年百度程序员被捕,我们有什么警示?开源云盘工具:Nextcloud21私有云盘构建更纯粹,微软Windows1021H2大更新将减少系统臃肿软件数量996操作系统是好是坏?