关于Java代码的一些优化技巧

2018-04-28

减少重复计算

for (int i = 0; i < list.size(); i++) {
  // do something;
}
for (int i = 0; int len = list.size(); i < len; i++) {
  // do something;
}
// 不要觉得麻烦, 尽量减少变量的重复计算, 这在大量数据集合遍历时非常有效.

不要创建大量的对象引用

for (; ;) {
  Object obj = new Object();
}

Object obj = null;
for (; ;) {
  obj = new Object();
}
// 能省就省.

卫语句

void fun(Date date) {
  if (isWorkDay(date)) {
    syso(date + " is work day.");
  } else {
    if (isWorkTime(date)) {
      syso(date + " is work time.");
    } else {
      // do something;
    }
  }
}

void fun(Date date) {
  if (isWorkDay(date)) {
    syso(date + " is work day.");
    return;
  }
  if (isWorkTime(date)) {
    syso(date + " is work time.");
    return;
  }
  // do something;
}
// 使用卫语句取代嵌套表达式, 使代码可读性更强且易维护

提取表达式

void fun(String browser) {
  if(
    browser.toUpperCase().indexOf("SAFARI") > -1 ||
    brower.toUpperCase().indexOf("CHROME") > -1 ||
    brower.toUpperCase().indexOf("FIREFOX") > -1 ||
    brower.toUpperCase().indexOf("IE") > -1){
      //do something...
  }
}

void fun(String browser) {
  String buc = browser.toUpperCase();
  boolean isSafari = buc.indexOf("SAFARI") > -1;
  boolean isChrome = buc.indexOf("CHROME") > -1;
  boolean isFireFox = buc.indexOf("FIREFOX") > -1;
  boolean isIe = buc.indexOf("IE") > -1;

  if(isSafair || isChrome || isFireFox || isIe){
      //do something
  }
}
// 任何时候, 可读性更重要.

资源的close()请分开操作

try {
	in.close();
	out.close();
} catch(Exception e) {
  //..
}

try {
	in.close();
} catch(Exception e) {
  //..
}
try {
	out.close();
} catch(Exception e) {
  //..
}
// 避免资源泄露

使用try - with - resources语法.

try (InputStream in = getIn();
    OutputStream out = getOut()) {

  // do something..
} catch (Exception e) {
  //..
}
// 任何AutoCloseable 和 Closeable的实现类都可以使用这种方式高效的关闭资源.

单例的最佳实践: 枚举

public class SingletonObj {
    private SingletonObj()  {}
    public static SingletonObj getInstance() {
        return Singleton.INSTANCE.getInstance();
    }

    private static enum Singleton {
        INSTANCE;
        private SingletonObj singletonObj;
        private Singleton() {
            singletonObj = new SingletonObj();
        }
        public SingletonObj getInstance() {
            return singletonObj;
        }
    }
}

// SingletonObj.getInstance(); 简洁高效且线程安全, 且支持序列化.

Lazy load 策略

String fun(int x) {
  User user = userService.find();
  if (x > 0) {
    return user.getName();
  }
  return String.Empty;
}

String fun(int x) {
  if (x > 0) {
    User user = userService.find();
    return user.getName();
  }
  return String.Empty;
}
// 总是在需要的时候, 才索取.

尽可能的使用缓存

final int MAX_ENTRIES = 1000;
final LoadingCache<String, String> mCache = CacheBuilder.newBuilder()
  .maximumSize(MAX_ENTRIES).build(new CacheLoader<String,String>() {
    @Override
    public String load(String key) throws Exception {
      return findByKey(key);
    }
  }
);

String output = mCache.getUnchecked(input);

// 缓存的实现方式有很多, 这里列举了guava提供的简单实现.

尽可能的预估集合的大小

Map<String, String> hashMap = null;
Map<String, String> convert(List<Field> list) {
  hashMap = new HashMap<>((int) Math.ceil(list.size() / 0.7));
  for (Field f : list) {
    hashMap.put(f.getTitle(), f);
  }
  return hashMap;
}
// 避免再次hash带来的不必要开销

预先编译正则表达式

boolean valid(List<String> urls) {
  Pattern p = Pattern.compile(_regex);
  for (String url : urls) {
    if (!p.matcher(url)) {
      return false;
    }
  }
  return true;
}

final static Pattern URL_PATTERN = Pattern.compile(_regex);
boolean valid(List<String> urls) {
  for (String url : urls) {
    if (!URL_PATTERN.matcher(url)) {
      return false;
    }
  }
  return true;
}

使用链式调用

public User {
  private String name;
  private String address;

  //getter..
  public User setName(String name) {
    this.name = name;
    return this;
  }
  //..
}

new User().setName("xx").setAddress("xxx");

当然, 这只是冰山一角。