From: juejin. Cn/post / 684490…
Steed leap, not ten steps; Inferior horse ten riding, gongnever give up. Improve the quality of the code, optimize the performance, you insist! If you work hard to eliminate the bad smell and keep accumulating it, you will not only improve your code, but you will also make your code clean.
In the back-end development, we often encounter various “pit”, such as the most familiar null pointer exception, session failure and so on, in fact, a big reason is that the development process is not a good combination of usage and practice, if we can pay attention to some code specifications and skills, we can make our development twice the result with half the effort! I’ll share my optimizations from the development process in the following three areas.
- Make your code perform better
- Make your code more elegant
- Keep your code bug-free
Make your code perform better
1.. When you need a primary key and value for a Map, you should iterate over entrySet()
Iterating over keySet() is correct when only the Map’s primary key is needed in the loop. However, when primary keys and values are needed, iterating through entrySet() is more efficient than iterating through keySet() and then getting values.
counter-examples
Map<String,String> map = ... ;for(String key: map.keySet()) { String value = map.get(key); . } Duplicate codeCopy the code
Is case
Map<String,String> map = ... ;for(Map.Entry<String, String> entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); . } Duplicate codeCopy the code
2. Use collection.isEmpty () to detect empty
Using collection.size () to detect empty logic is fine, but using collection.isEmpty () makes the code more readable and gives better performance. Any collection.isempty () implementation has a time complexity of O(1), but some collection.size () implementations may have a time complexity of O(n).
counter-examples
if(collection.size() == 0) { ... } Duplicate codeCopy the code
Is case
if(collection.isEmpty()) { ... } Duplicate codeCopy the code
3. Set initialization to specify the size as much as possible
Java collection classes are very convenient to use, but see the source code, collections are also limited in size. The time complexity of each expansion is likely to be O(n), so it is possible to specify the predictable size of the collection to reduce the number of expansion of the collection.
counter-examples
int[] arr = new int[]{1, 2, 3};
List<Integer> list = new ArrayList<>();
for(int i : arr) { list.add(i); } Duplicate codeCopy the code
Is case
int[] arr = new int[]{1, 2, 3};
List<Integer> list = new ArrayList<>(arr.length);
for(int i : arr) { list.add(i); } Duplicate codeCopy the code
4. String concatenation using StringBuilder
Normal string concatenation is optimized by Java at compile time, but string concatenation in a loop cannot be optimized at Compile time, so StringBuilder is used instead. counter-examples
String s = "";
for(int i = 0; i < 10; i++) { s += i; } Duplicate codeCopy the code
Is case
String a = "a";
String b = "b";
String c = "c"; String s = a + b + c; StringBuilder sb = new StringBuilder();for(int i = 0; i < 10; i++) { sb.append(i); // In the loop, the Java compiler is unable to optimize, so copy the code manually using StringBuilder}Copy the code
5. Random access to List
The difference between arrays and linked lists: Arrays are more efficient for random access. What if I want to randomly access the List when I call a method and I don’t know whether the List or array is implemented internally? You can determine if it implements the RandomAccess interface.
Is case
List<Integer> list = otherService.getList();ifPrintln (list.get(list.size() -1)); list.get(list.size() -1); list.get(list.size() -1); }else{// Internal may be linked list implementation, random access is inefficient} copy codeCopy the code
6. Use Set when calling collection. contains method frequently
In the Java collection library, the general time complexity of the contains method of List is O(n). If the contains method needs to be called frequently in the code to find data, you can first convert the List into a HashSet implementation. Reduce the time complexity of O(n) to O(1).
counter-examples
ArrayList<Integer> list = otherService.getList();
for(int i = 0; i <= Integer.MAX_VALUE; I ++) {// time complexity O(n) list.contains(I); } Duplicate codeCopy the code
Is case
ArrayList<Integer> list = otherService.getList();
Set<Integer> set = new HashSet(list);
for(int i = 0; i <= Integer.MAX_VALUE; I ++) {// time complexity O(1) set.contains(I); } Duplicate codeCopy the code
Make your code more elegant
1. Add capital L after long integer constants
counter-examples
long value = 1l; long max = Math.max(1L, 5); Copy the codeCopy the code
Is case
long value = 1L; long max = Math.max(1L, 5L); Copy the codeCopy the code
2. Do not use mana
When you’re writing a piece of code, using magic values may seem obvious, but when you’re debugging they don’t. This is why you need to define magic values as readable constants. However, -1, 0, and 1 are not considered magic values.
counter-examples
for (int i = 0; i < 100; i++){
...
}
if(a == 100) { ... } Duplicate codeCopy the code
Is case
private static final int MAX_COUNT = 100;
for (int i = 0; i < MAX_COUNT; i++){
...
}
if(count == MAX_COUNT) { ... } Duplicate codeCopy the code
3. Do not use collection implementations to assign static member variables
For static member variables of collection types, do not use the collection implementation to assign values; instead, use static code blocks.
counter-examples
private static Map<String, Integer> map = new HashMap<String, Integer>() {
{
put("a", 1);
put("b", 2); }}; private static List<String> list = new ArrayList<String>() { { add("a");
add("b"); }}; Copy the codeCopy the code
Is case
private static Map<String, Integer> map = new HashMap<>();
static {
map.put("a", 1);
map.put("b", 2);
};
private static List<String> list = new ArrayList<>();
static {
list.add("a");
list.add("b"); }; Copy the codeCopy the code
4. Delete unused private methods and fields
Remove unused private methods and fields, making the code simpler and more maintainable. If you need to reuse it, you can retrieve it from the history commit.
counter-examples
public class DoubleDemo1 {
private int unusedField = 100;
private void unusedMethod() {... } public int sum(int a, int b) {returna + b; }} Copy the codeCopy the code
Is case
public class DoubleDemo1 {
public int sum(int a, int b) {
returna + b; }} Copy the codeCopy the code
5. Utility classes should mask constructors
Utility classes are a collection of static fields and functions that should not be instantiated. However, Java adds an implicit public constructor for every class that does not explicitly define a constructor. So, to avoid Java “white” errors, you should explicitly define the private constructor to mask the implicit public constructor. counter-examples
Public class final MathUtils {public static final double PI = 3.1415926d; public static int sum(int a, int b) {returna + b; }} Copy the codeCopy the code
Is case
Public class final MathUtils {public static final double PI = 3.1415926d; privateMathUtils() {}
public static int sum(int a, int b) {
returna + b; }} Copy the codeCopy the code
6. Public static constants should be accessed through classes
Although it is allowed to access public static constants through instances of a class, it is easy to think that every instance of a class has a public static constant. Therefore, public static constants should be accessed directly through the class.
counter-examples
public class User {
public static final String CONST_NAME = "name"; . } User user = new User(); String nameKey = user.CONST_NAME; Copy the codeCopy the code
Is case
public class User {
public static final String CONST_NAME = "name"; . } String nameKey = User.CONST_NAME; Copy the codeCopy the code
7. Do not use NullPointerException
Null-pointer exceptions should be avoided by code (such as detecting non-null) rather than handled by catching exceptions.
counter-examples
public String getUserName(User user) {
try {
return user.getName();
} catch (NullPointerException e) {
returnnull; }} Copy the codeCopy the code
Is case
public String getUserName(User user) {
if (Objects.isNull(user)) {
return null;
}
returnuser.getName(); } Duplicate codeCopy the code
8. Use string.valueof (value) instead of “”+value
When converting other objects or types to strings, it is more efficient to use string.valueof (value) rather than “”+value.
counter-examples
int i = 1;
String s = ""+ i; Copy the codeCopy the code
Is case
int i = 1; String s = String.valueOf(i); Copy the codeCopy the code
9. Add the @deprecated annotation to obsolete code
When a piece of code is obsolete but cannot be removed for compatibility and does not want to be used in the future, you can mark it with the @deprecated annotation. Add @deprecated to the documentation comment to explain and provide an alternative.
Is case
/** * save ** @deprecated This method is inefficient, please replace it with {@link newSave()} */ @deprecated public voidsave() {/ /doSomething} copies the codeCopy the code
Keep your code bug-free
1. Disallow constructor BigDecimal(double)
BigDecimal(Double) carries the risk of loss of precision and can cause business logic exceptions in scenarios where exact calculations or value comparisons are performed.
counter-examples
BigDecimal value = new BigDecimal(0.1d); / / 0.100000000000000005551115... Copy the codeCopy the code
Is case
BigDecimal value = BigDecimal. The valueOf (0.1 D);; // 0.1 copy the codeCopy the code
2. Return empty arrays and collections instead of NULL
Returns null, requiring the caller to enforce null detection, or a null-pointer exception will be thrown. Return an empty array or collection, effectively preventing the caller from throwing a null-pointer exception if null is not detected, and making the code cleaner by removing null-detecting statements.
counter-examples
public static Result[] getResults() {
return null;
}
public static List<Result> getResultList() {
return null;
}
public static Map<String, Result> getResultMap() {
return null;
}
public static void main(String[] args) {
Result[] results = getResults();
if(results ! = null) {for (Result result : results) {
...
}
}
List<Result> resultList = getResultList();
if(resultList ! = null) {for (Result result : resultList) {
...
}
}
Map<String, Result> resultMap = getResultMap();
if(resultMap ! = null) {for(Map.Entry<String, Result> resultEntry : resultMap) { ... }}} copy the codeCopy the code
Is case
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();
}
public static void main(String[] args) {
Result[] results = getResults();
for (Result result : results) {
...
}
List<Result> resultList = getResultList();
for (Result result : resultList) {
...
}
Map<String, Result> resultMap = getResultMap();
for(Map.Entry<String, Result> resultEntry : resultMap) { ... }} Copy the codeCopy the code
3. Call equals using constants or determinations in preference
The equals method of an object is prone to null-pointer exceptions and should be called using constants or objects that are determined to have values. Of course, using the java.util.objects.equals () method is a best practice.
counter-examples
public void isFinished(OrderStatus status) {
returnstatus.equals(OrderStatus.FINISHED); // Possible null-pointer exception} copy codeCopy the code
Is case
public void isFinished(OrderStatus status) {
return OrderStatus.FINISHED.equals(status);
}
public void isFinished(OrderStatus status) {
returnObjects.equals(status, OrderStatus.FINISHED); } Duplicate codeCopy the code
4. The enumerated property fields must be private and immutable
Enumerations are often used as constants, and their properties can be easily modified if there are public property fields or set field methods in the enumeration. Ideally, property fields in enumerations are private and assigned in private constructors, with no corresponding Setter methods, preferably with a final modifier.
counter-examples
public enum UserStatus {
DISABLED(0, "Disabled"),
ENABLED(1, "Enable");
public int value;
private String description;
private UserStatus(int value, String description) {
this.value = value;
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) { this.description = description; }} Copy the codeCopy the code
Is case
public enum UserStatus {
DISABLED(0, "Disabled"),
ENABLED(1, "Enable");
private final int value;
private final String description;
private UserStatus(int value, String description) {
this.value = value;
this.description = description;
}
public int getValue() {
return value;
}
public String getDescription() {
returndescription; }} Copy the codeCopy the code
5. Be careful with string.split (String regex)
The String split method, passed in the delimited String is a regular expression! Some key words (such as. | etc.) need to escape.
counter-examples
"a.ab.abc".split("."); // Result is []"a|ab|abc".split("|"); // The result is ["a"."|"."a"."b"."|"."a"."b"."c"Copy codeCopy the code
Is case
"a.ab.abc".split("\ \."); // The result is ["a"."ab"."abc"]
"a|ab|abc".split("\ \ |"); // The result is ["a"."ab"."abc"]Copy the code