Closed vieyahn2017 closed 4 years ago
原代码(需要计算 n 次 key 的 hash)
for (String key : this.configurations.keySet()) {
ConfigurationItem item = this.configurations.get(key);
LOG.info("config item: key=" + key + ";pattern=" + item.stringPattern + ";service=" + item.microserviceName + ";versionRule=" + item.versionRule);
}
优化之后 (不需要计算 hash,只需要每次从 entry 取值就行)
configurations.entrySet().forEach(stringConfigurationItemEntry -> {
ConfigurationItem item = stringConfigurationItemEntry.getValue();
LOG.info("config item: key=" + stringConfigurationItemEntry.getKey() + ";pattern=" + item.stringPattern + ";service=" + item.microserviceName + ";versionRule=" + item.versionRule);
});
源代码:
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
原代码
public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
if (servers.size() == 0) {
return null;
}
优化之后
public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
if (servers.isEmpty()) {
return null;
}
源码解析(ArrayList)
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
源码解析(BitSet)
public int size() {
int size = 0;
if (bits.length > 0) {
for (int n = 0; n < bits.length; n++) {
final long mask = bits[n];
if (mask != 0) {
size += Long.bitCount(mask);
}
}
}
// index.length is zero or all index[n] values are zero
return size;
}
public boolean isEmpty() {
if (bits.length > 0) {
for (int n = 0; n < bits.length; n++) {
final long mask = bits[n];
if (mask != 0) {
return false;
}
}
}
// index.length is zero or all index[n] values are zero
return true;
}
先看一个完全遵循的例子:java.util.Math
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
}
再看不遵循 final 的例子:java.util.Arrays
public class Arrays {
/**
* The minimum array length below which a parallel sorting
* algorithm will not further partition the sorting task. Using
* smaller sizes typically results in memory contention across
* tasks that makes parallel speedups unlikely.
*/
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}
}
再看一个不遵循 final 和 私有化构造方法的例子:
public class StringUtils {
/**
*
{@code StringUtils} instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* {@code StringUtils.trim(" foo ");}.
*
*
This constructor is public to permit tools that require a JavaBean
* instance to operate.
*/
public StringUtils() {
super();
}
}
System.out.println(new BigDecimal(0.1)); //0.1000000000000000055511151231257827021181583404541015625
System.out.println(BigDecimal.valueOf(0.1));
//0.1
下面三个用法有区别么?
a == b 与 Objects.equals(a, b)
a == null 与 Objects.isNull(a)
val.toString() 与 String.valueOf(val)
String 源码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Objects 源码
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
public static boolean isNull(Object obj) {
return obj == null;
}
//Before
return null;
//After
return Collections.emptyList();
return new String[0];
原代码
public enum SchemaFormat {
SWAGGER(".yaml"),
HTML(".html");
private String suffix;
SchemaFormat(String suffix) {
this.suffix = suffix;
}
public String getSuffix() {
return suffix;
}
}
优化后
public enum SchemaFormat {
SWAGGER(".yaml"),
HTML(".html");
private final String suffix;
SchemaFormat(String suffix) {
this.suffix = suffix;
}
public String getSuffix() {
return suffix;
}
}
避免 Java ”坏味道“ 的一些技术细节
源自 https://github.com/apache/servicecomb-java-chassis/pull/1353