java代码优化

1:多余的 if/else,对于boolean值,避免不必要的等式判断。

反例: 

 boolean ret;
 int i=0;
 if(i==0)
 {
     ret=true;
 }

 else
 {
   ret=false;
 }

类似上面这种写法if/else  可以简写: 

int i=0;
boolean ret=(i==0)?true:false;

2:多余的 else

public static String Login(String name)
{
    String reponseJson="";
    if(name==null)
    {
        reponseJson= "请输入用户名";
    }
    else
    {
       //登录方法
        reponseJson="";
    }
    
    return  reponseJson;
}

完全可以提前 return,进而干掉 else 分支

public static String Login(String name)
{
    String reponseJson="";
    if(name==null)
    {
        reponseJson= "请输入用户名";
    }
     //登录方法
    reponseJson="";
   
    return  reponseJson;
}
  • 简单就是美,代码写的越少,犯错的几率就越小。
  • 提前终止程序,绝大多数情况下,会节省很多不必要的开销(会减少很多无效的判断,减少无效变量、对象的创建)。
  • 每种编程语言都离不开 if/else 进行条件判断,如果在编码时,存在过多的 if/else 嵌套,代码的可读性就会下降,后期维护难度就会大大提高。

3:随处可见的判空逻辑。

if(name == null || "".equals(name)) {

}

很多时候都需要做非空检查

确实有点不雅观。

很多同学会想着,自己封装 StringUtils 工具类

可以引用 

import org.apache.commons.lang3.StringUtils;
if(StringUtils.isBlank(name))
 {

     return  "";
 }

4:完成对象间的属性 Copy,编写冗长的代码。

BeanUtils.copyProperties(EntityOld,EntityNew);

5 for

所以例如下面的操作:

for (int i = 0; i < list.size(); i++)
{...}

建议替换为:

for (int i = 0, length = list.size(); i < length; i++)
{...}

 

6 尽量采用懒加载的策略,即在需要的时候才创建

例如:

String str = "aaa";
if (i == 1)
{
  list.add(str);
}

建议替换为:

if (i == 1)
{
  String str = "aaa";
  list.add(str);
}

7当复制大量数据时,使用System.arraycopy()命令

8 循环内不要不断创建对象引用

例如:

for (int i = 1; i <= counts; i++)
{
    Object obj = new Object(); }

这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:

Object obj = null;
for (int i = 0; i <= counts; i++)
{
    obj = new Object(); }

9 尽量避免随意使用静态变量

要知道,当某个对象被定义为static的变量所引用,那么gc通常是不会回收这个对象所占有的堆内存的,如:

public class A
{
    private static B b = new B();  
}

10 将常量声明为static final,并以大写命名

这样在编译期间就可以把这些内容放入常量池中,避免运行期间计算生成常量的值。另外,将常量的名字以大写命名也可以方便区分出常量与变

11 字符串变量和字符串常量equals的时候将字符串常量写在前面

这是一个比较常见的小技巧了,如果有以下代码:

String str = "123";
if (str.equals("123"))
{
    ...
}

建议修改为:

String str = "123";
if ("123".equals(str))
{
    ...
}

这么做主要是可以避免空指针异常

12请知道,在java中if (i == 1)和if (1 == i)是没有区别的,但从阅读习惯上讲,建议使用前者

 

13不要对数组使用toString()方法

看一下对数组使用toString()打印出来的是什么:

public static void main(String[] args) {

int[] is = new int[]{2, 5, 3};

System.out.println(is.toString());

}

14不要对超出范围的基本数据类型做向下强制转型

这绝不会得到想要的结果:

public static void main(String[] args)
{
    long l = 123456789645454L;
    int i = (int)l;
    System.out.println(i);
}
15 公用的集合类中不使用的数据一定要及时remove掉

16把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+""最慢

17使用最有效率的方式去遍历Map

遍历Map的方式有很多,通常场景下我们需要的是遍历Map中的Key和Value,那么推荐使用的、效率最高的方式是:

public static void main(String[] args)
{

HashMap hmp = new HashMap();
hmp.put("324", "234");
hmp.put("33524", "234");

long startTime=0;
long endTime=0;
startTime = System.currentTimeMillis();
Set> entrySet = hmp.entrySet();
Iterator> iter = entrySet.iterator();
while (iter.hasNext())
{
    Map.Entry entry = iter.next();
    System.out.println(entry.getKey() + "\t" + entry.getValue());
}
endTime = System.currentTimeMillis();
System.out.println("1程序运行时间:" + (endTime - startTime) + "ms");

    startTime = System.currentTimeMillis();
    Iterator> iterator = hmp.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry entry = iterator.next();
        System.out.println("key"+  entry.getKey() + "\t" + entry.getValue());
    }
    endTime = System.currentTimeMillis();
    System.out.println("2程序运行时间:" + (endTime - startTime) + "ms");

    startTime = System.currentTimeMillis();
    for (String key : hmp.keySet()) {

        System.out.println("key"+key + "\t" +  hmp.get(key));
    }
    endTime = System.currentTimeMillis();
    System.out.println("3程序运行时间:" + (endTime - startTime) + "ms");
}
结果:

33524    234
324    234
程序运行时间:2ms
key33524    234
key324    234
程序运行时间:0ms
key33524    234
key324    234
程序运行时间:1ms

18对资源的close()建议分开操作

19 对于ThreadLocal使用前或者使用后一定要先remove

20 long或者Long初始赋值时,使用大写的L而不是小写的l,因为字母l极易与数字1混淆,这个点非常细节,值得注意

21 所有重写的方法必须保留@Override注解

22 循环体内不要使用"+"进行字符串拼接,而直接使用StringBuilder不断append

23 在存在大量字符串拼接或者大型字符串拼接的时候,尽量使用StringBuilder和StringBuffer,确定 StringBuffer的容量

24避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降,JDK7之后,可以使用ThreadLocalRandom来获取随机数

25 静态类、单例类、工厂类将它们的构造函数置为private

26时间选择 :  循环中用System.nanoTime 因为精度高,平时用System.currentTimeMillis()能和data转换

27.float和double   要性能和内存用float,要精度高用double

28.集合初始化尽量指定大小

int[] arr=new int[]{1,2,3};
List<Integer> list=new ArrayList<>(arr.length);

29.长整型常量后添加大写 L

在使用长整型常量值时,后面需要添加 L ,必须是大写的 L ,不能是小写的 l ,小写 l 容易跟数字 1 混淆而造成误解。

30.建议使用 try-with-resources 语句

Java 7 中引入了 try-with-resources 语句,该语句能保证将相关资源关闭,优于原来的 try-catch-finally 语句,并且使程序代码更安全更简洁。

31.删除未使用的私有方法和字段

32.删除未使用的局部变量

33公有静态常量应该通过类访问

34.禁止使用构造方法 BigDecimal(double)

35.返回空数组和空集合而不是 null

反例:

private static  List<Integer> getList()
{
    
    return null;
}

正例:

private static  List<Integer> getList()
{

    return Collections.emptyList();
}

36.枚举的属性字段必须是私有不可变

37.小心 String.split(String regex)

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

38 如果只是查找单个字符的话,用charAt()代替startsWith()

39 使用移位操作来代替'a / b'操作

"/"是一个很“昂贵”的操作,使用移位操作将会更快更有效。

例子:

private static void calculates(int a)
{


   int div = a /4;
   int div2 = a / 8;
   int temp = a / 3;
}
更正:
public static void calculate2(int a) {
    int div = a >> 2;
    int div2 = a >> 4;
    int temp = a / 3;
}

40使用移位操作代替'a * b'

例子:

private static void calculates(int a)
{
   int div = a *4;
   int div2 = a* 8;
   int temp = a * 3;
}

更正:

public static void calculate2(int a) {
    int div = a << 2;
    int div2 = a << 4;
    int temp = a* 3;
}

41在字符串相加的时候,使用 ' ' 代替 " ",如果该字符串只有一个字符的话

例子:

 

private static void Str(String s)
{
    String string = s + "d"; // violation.
    string = "abc" + "d";      // violation.
}

更正:

public static void Str2(String s) {
    String string = s + 'd'; // violation.
    string = "abc" + 'd';      // violation.
}

42 把try/catch块放入循环体内,会极大的影响性能,如果编译JIT被关闭或者你所使用的是一个不带JIT的JVM,性能会将下降21%之多!

43 尽可能的使用栈变量,访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期

你可能感兴趣的:(java代码优化)