Continuously optimize the code, improve the quality of the code, is one of the effective means to enhance the vitality of the system. In software systems thinking, there is a saying “Less coding, more thinking”, as well as a slang phrase “Think more, code Less”. Therefore, we think more and summarize more in coding, and strive to improve their coding level, so as to write more elegant, higher quality, more efficient code.
In JAVA programs, most of the performance problems are not caused by the JAVA language, but by the program itself. Developing good coding habits is important and can significantly improve application performance.
1. Use generic utility functions
Case a
Incomplete writing:
thisName ! = null && thisName.equals(name);Copy the code
A more complete way of writing:
(thisName == name) || (thisName ! = null && thisName.equals(name));Copy the code
Recommended scheme:
Objects.equals(name, thisName);
Copy the code
Case 2
Symptom Description:
! (list == null || list.isEmpty());Copy the code
Recommended scheme:
CollectionUtils.isNotEmpty(list);
Copy the code
The main benefits
- Functional programming, reduced business code, logic at a glance;
- General tool function, logic considerate, low probability of problems.
- Common Java utility classes
Reduce the level of function code
If you want to make a function elegant, it is recommended that the code level be between 1 and 4. Too much indentation makes the function difficult to read.
Case 1: Use return to return the function early
Symptom Description:
Public Double getUserBalance(Long userId) {User User = getUser(userId); if (Objects.nonNull(user)) { UserAccount account = user.getAccount(); if (Objects.nonNull(account)) { return account.getBalance(); } } return null; }Copy the code
Recommended scheme:
Public Double getUserBalance(Long userId) {public Double getUserBalance(Long userId) {User User = getUser(userId); if (Objects.isNull(user)) { return null; } // Get user account UserAccount account = user.getAccount(); if (Objects.isNull(account)) { return null; } // Return account.getBalance(); }Copy the code
Case 2: Use continue to end the loop prematurely
Symptom Description:
Public double getTotalBalance(List<User> userList) {double totalBalance = 0.0d; For (User User: userList) {UserAccount account = user.getAccount(); If (objects.nonnull (account)) {Double balance = account.getBalance(); if (Objects.nonNull(balance)) { totalBalance += balance; }} return totalBalance; }Copy the code
Recommended scheme:
Public double getTotalBalance(List<User> userList) {double totalBalance = 0.0d; For (User User: userList) {UserAccount account = user.getAccount(); if (Objects.isNull(account)) { continue; } Double balance = account.getBalance(); if (Objects.nonNull(balance)) { totalBalance += balance; } // return totalBalance; }Copy the code
- Special instructions
Other ways: In the body of the loop, call the function getUserBalance from Case 1 (to get the user balance) and then add the balance. It is recommended to use continue at most once in the body of the loop. If you need to use continue multiple times, it is recommended that you wrap the body of the loop as a function.
Case 3: Using conditional expression functions to reduce levels
The main benefits
- Code levels are reduced, code indentation is reduced;
- Module division clear, easy to read maintenance.
Encapsulate conditional expression functions
Case 1: Encapsulate a simple conditional expression as a function
Symptom Description:
Public double getTicketPrice(Date currDate) {if (objects.nonnull (currDate) && currDate.after(DISCOUNT_BEGIN_DATE) && currDate.before(DISCOUNT_END_DATE)) { return TICKET_PRICE * DISCOUNT_RATE; } return TICKET_PRICE; }Copy the code
Recommended scheme:
Public double getTicketPrice(Date currDate) {if (isDiscountDate(currDate)) {return TICKET_PRICE * DISCOUNT_RATE; } return TICKET_PRICE; } private static Boolean isDiscountDate(Date currDate) {return objects.nonnull (currDate) && currDate.after(DISCOUNT_BEGIN_DATE) && currDate.before(DISCOUNT_END_DATE); }Copy the code
Case 2: Encapsulate complex conditional expressions as functions
Symptom Description:
Public List<User> getRichUserList(List<User> userList) {List<User> richUserList = new ArrayList<>(); For (User User: userList) {UserAccount account = user.getAccount(); If (objects.nonnull (account)) {Double balance = account.getBalance(); If (objects.nonnull (balance) &&balance.com pareTo(RICH_THRESHOLD) >= 0) {// add richuserlist.add (user); }} return richUserList; }Copy the code
Recommended scheme:
Public List<User> getRichUserList(List<User> userList) {List<User> richUserList = new ArrayList<>(); For (User User: userList) {if (isRichUser(User)) {richuserlist.add (User); }} return richUserList; } private Boolean isRichUser(User User) {UserAccount account = user.getAccount(); if (Objects.isNull(account)) { return false; } Double balance = account.getBalance(); if (Objects.isNull(balance)) { return false; Return balance.compareTo(RICH_THRESHOLD) >= 0; }Copy the code
The above code can also be implemented with filtering using Stream programming.
The main benefits
- The conditional expression is separated from the business function to make the business logic clearer.
- Encapsulated conditional expressions are stand-alone functions that can be used repeatedly in code.
Fourth, try to avoid unnecessary null pointer judgment
This chapter is only applicable to the internal code of the project, and the code is their own understanding, so as to avoid unnecessary null pointer judgment. For third-party middleware and system interfaces, null pointer judgment must be done to ensure the robustness of the code.
Case 1: Call the function to ensure that the parameter is not empty, the function to be called as far as possible to avoid unnecessary null pointer judgment
Symptom Description:
User User = new User(); . CreateUser (user); Private void createUser(User User){if(objects.isnull (User)) {return; } // Create user information userdao.insert (user); userRedis.save(user); }Copy the code
Recommended scheme:
User User = new User(); . CreateUser (user); // createUser function private void createUser(User User){// createUser information userdao.insert (User); userRedis.save(user); }Copy the code
Case 2: The called function ensures that the return is not null, and the calling function tries to avoid unnecessary null pointer judgment
Symptom Description:
Public void saveUser(Long ID, String name) {User User = buildUser(id, name); If (objects.isnull (user)) {throw new BizRuntimeException(" build user information is empty "); } // Save user information userdao.insert (user); userRedis.save(user); } private User buildUser(Long ID, String name) {User User = new User(); user.setId(id); user.setName(name); return user; }Copy the code
Recommended scheme:
Public void saveUser(Long ID, String name) {User User = buildUser(id, name); // Save user information userdao.insert (user); userRedis.save(user); } private User buildUser(Long ID, String name) {User User = new User(); user.setId(id); user.setName(name); return user; }Copy the code
Case 3: The assignment logic ensures that the list item is not empty, and the processing logic tries to avoid unnecessary null pointer judgment
Symptom Description:
List<UserDO> userList = userdao.queryAll (); if (CollectionUtils.isEmpty(userList)) { return; List<UserVO> userVoList = new ArrayList<>(userlist.size ()); for (UserDO user : userList) { UserVO userVo = new UserVO(); userVo.setId(user.getId()); userVo.setName(user.getName()); userVoList.add(userVo); } for (UserVO UserVO: userVoList) {if (objects.isnull (UserVO)) {continue; } // Handle the related logic... }Copy the code
Recommended scheme:
List<UserDO> userList = userdao.queryAll (); if (CollectionUtils.isEmpty(userList)) { return; List<UserVO> userVoList = new ArrayList<>(userlist.size ()); for (UserDO user : userList) { UserVO userVo = new UserVO(); userVo.setId(user.getId()); userVo.setName(user.getName()); userVoList.add(userVo); } for (UserVO UserVO: userVoList) { }Copy the code
Case 4: MyBatis query function return list and data items are not empty, can not use the null pointer to judge
MyBatis is an excellent persistence layer framework and is one of the most widely used database middleware in projects. Through the analysis of MyBatis source code, the list and data items returned by the query function are not empty, in the code can not be null pointer judgment.
There is nothing wrong with this way of writing, but it is too conservative.
Public List<UserVO> queryUser(Long ID, String name) {List<UserDO> userList = userdao.query (id, String name); name); if (Objects.isNull(userList)) { return Collections.emptyList(); List<UserVO> voList = new ArrayList<>(userlist.size ()); For (UserDO user: userList) {// Determine whether the object is empty if (objects.isnull (user)) {continue; } // Add user information UserVO vo = new UserVO(); BeanUtils.copyProperties(user, vo); voList.add(vo); } // Return the user list. }Copy the code
Recommended scheme:
Public List<UserVO> queryUser(Long ID, String name) {List<UserDO> userList = userdao.query (id, String name); name); List<UserVO> voList = new ArrayList<>(userlist.size ()); for (UserDO user : userList) { UserVO vo = new UserVO(); BeanUtils.copyProperties(user, vo); voList.add(vo); } // Return the user list. }Copy the code
The main benefits
- Avoid unnecessary null pointer judgment, streamline business code processing logic, improve the operation efficiency of business code;
- These unnecessary null Pointers are basically Death code that never executes, and removal helps with code maintenance.
Five, internal function parameters as far as possible to use the basic type
Example 1: Use basic types for internal function arguments
Symptom Description:
// Double price = 5.1d; int number = 9; double total = calculate(price, number); Private double calculate(double price, Integer number) {return price * number; }Copy the code
Recommended scheme:
// Double price = 5.1d; int number = 9; double total = calculate(price, number); Private double calculate(double price, int number) {return price * number; }Copy the code
Case 2: Use the base type as much as possible for the internal function return value
Public double getOrderAmount(List<Product> productList) {double amount = 0.0d; for (Product product : productList) { if (Objects.isNull(product) || Objects.isNull(product.getPrice()) || Objects.isNull(product.getNumber())) { continue; } amount += calculate(product.getPrice(), product.getNumber()); } return amount; } private Double calculate(Double price, Double number) {return price * number; }Copy the code
Recommended scheme:
Public double getOrderAmount(List<Product> productList) {double amount = 0.0d; for (Product product : productList) { if (Objects.isNull(product) || Objects.isNull(product.getPrice()) || Objects.isNull(product.getNumber())) { continue; } amount += calculate(product.getPrice(), product.getNumber()); } return amount; } private double calculate(double price, double number) {return price * number; }Copy the code
To illustrate this phenomenon, a better approach is to use Stream programming.
The main benefits
- Internal functions use base types as much as possible, avoiding the packaging and unpacking of implicitly encapsulated types
- Internal function arguments use base types, which syntactically avoid null pointer judgments for internal function arguments
- The return value of the internal function uses the underlying type, which syntactically avoids null pointer judgment of the return value of the calling function
Try to avoid returning null arrays and lists
Case 1: Try to avoid returning array null, causing unnecessary null pointer judgment
Symptom Description:
UserVO[] users = queryUser(); if (Objects.nonNull(users)) { for (UserVO user : Private UserVO[] queryUser() {List<UserDO> userList = userdao.queryAll (); if (CollectionUtils.isEmpty(userList)) { return null; UserVO[] users = new UserVO[userlist.size ()]; for (int i = 0; i < userList.size(); i++) { UserDO user = userList.get(i); users[i] = new UserVO(); users[i].setId(user.getId()); users[i].setName(user.getName()); } // Return user array return users; }Copy the code
Recommended scheme:
UserVO[] users = queryUser(); for (UserVO user : Private UserVO[] queryUser() {List<UserDO> userList = userdao.queryAll (); if (CollectionUtils.isEmpty(userList)) { return new UserVO[0]; UserVO[] users = new UserVO[userlist.size ()]; for (int i = 0; i < userList.size(); i++) { UserDO user = userList.get(i); users[i] = new UserVO(); users[i].setId(user.getId()); users[i].setName(user.getName()); } // Return user array return users; }Copy the code
Case 2: Try not to return the list as null, causing unnecessary null pointer judgment
Symptom Description:
List<UserVO> userList = queryUser(); if (Objects.nonNull(userList)) { for (UserVO user : Private List<UserVO> queryUser(){private List<UserVO> queryUser(){List<UserDO> userList = userDAO.queryAll(); if(CollectionUtils.isEmpty(userList)) { return null; List<UserVO> userVoList = new ArrayList<>(userlist.size ()); for(UserDO user : userList) { UserVO userVo = new UserVO(); userVo.setId(user.getId()); userVo.setName(user.getName()); userVoList.add(userVo); } // Return userVoList; }Copy the code
Recommended scheme:
List<UserVO> userList = queryUser(); for (UserVO user : Private List<UserVO> queryUser(){// query the userList List<UserDO> userList = userDAO.queryAll(); if(CollectionUtils.isEmpty(userList)) { return Collections.emptyList(); List<UserVO> userVoList = new ArrayList<>(userlist.size ()); for(UserDO user : userList) { UserVO userVo = new UserVO(); userVo.setId(user.getId()); userVo.setName(user.getName()); userVoList.add(userVo); } // Return userVoList; }Copy the code
The main benefits
- Ensure that the returned array and list are not null to avoid calling the null pointer to the function
Encapsulate the function’s passing parameters
Case 1: When too many parameters are passed in, encapsulate them as parameter classes
The Java specification does not allow functions to take too many arguments, making them difficult to maintain or extend. Symptom Description:
Public void modifyUser(Long ID, String name, String phone, Integer age, Integer sex, String address, String description) {// Implement logic}Copy the code
Recommended scheme:
Public void modifyUser(User User) {// Implementation content} // User class @getter@setter@toString private class User{private Long id; private String name; private String phone; private Integer age; private Integer sex; private String address; private String description; }Copy the code
Case 2: When passing group parameters, encapsulate them as parameter classes
Now that arguments are grouped, you need to encapsulate a class to describe this phenomenon. Symptom Description:
Public double getDistance(double x1, double y1, double x2, double y2) {Copy the code
Recommended scheme:
Public double getDistance(Point point1, Point point2) {getter@setter@toString private class Point{private double x; private double y; }Copy the code
The main benefits
- Encapsulate too many function parameters as classes, making the function easier to expand and maintain;
- Encapsulate group function parameters as classes to make business concepts clearer and clearer.
Use return to simplify unnecessary code
Case 1: Delete unnecessary if
Symptom Description:
Public Boolean isPassed(Double passRate) {if (objects.nonnull (passRate) && passRate.compareTo(PASS_THRESHOLD) >= 0) { return true; } return false; }Copy the code
Recommended scheme:
Public Boolean isPassed(Double passRate) {return objects.nonnull (passRate) && passRate.compareTo(PASS_THRESHOLD) >= 0; }Copy the code
Case 2: Delete unnecessary else
Symptom Description:
Public double settleSalary(Long workId, Long workId) Int workDays) {if (isQualified(workId)) {return settlefiedsalary (workDays); } else { return settleUnqualifiedSalary(workDays); }}Copy the code
Recommended scheme:
Public double settleSalary(Long workId, Long workId) Int workDays) {if (isQualified(workId)) {return settlefiedsalary (workDays); } return settleUnqualifiedSalary(workDays); }Copy the code
Case 3: Delete unnecessary variables
Symptom Description:
Public List<UserDO> queryUser(Long ID, String name) {UserQuery UserQuery = new UserQuery(); userQuery.setId(id); userQuery.setName(name); List<UserDO> userList = userDAO.query(userQuery); return userList; }Copy the code
Recommended scheme:
Public List<UserDO> queryUser(Long ID, String name) {UserQuery UserQuery = new UserQuery(); userQuery.setId(id); userQuery.setName(name); return userDAO.query(userQuery); }Copy the code
The main benefits
- Simplify unnecessary code to make it look cleaner
Optimize code with temporary variables
In some code, it is common to see a.geb ().getc ()… The way getN() is written has poor code robustness and readability. Suggestion: eliminate cascading function calls, use temporary variables to split, and do a good job of object null pointer check.
Case 1: Use temporary variables to clarify logic
Symptom Description:
Private Boolean isRichUser(User User) {return objects.nonnull (user.getAccount()) && Objects.nonNull(user.getAccount().getBalance()) && user.getAccount().getBalance().compareTo(RICH_THRESHOLD) >= 0; }Copy the code
This is a favorite of code lite geeks, but very unreadable. Recommended scheme:
Private Boolean isRichUser(User User) {private Boolean isRichUser(User User) {UserAccount account = user.getAccount(); if (Objects.isNull(account)) { return false; } Double balance = account.getBalance(); if (Objects.isNull(balance)) { return false; Return balance.compareTo(RICH_THRESHOLD) >= 0; }Copy the code
This solution increases the number of lines of code, but the logic is clearer. Sometimes, when the simplicity of code conflicts with readability, the preference is to preserve the readability of code.
Case 2: Simplify code with temporary variables
Symptom Description:
Public UserVO buildUser(UserDO user) {UserVO vo = new UserVO(); vo.setId(user.getId()); vo.setName(user.getName()); if (Objects.nonNull(user.getAccount())) { vo.setBalance(user.getAccount().getBalance()); vo.setDebt(user.getAccount().getDebt()); } return vo; }Copy the code
Recommended scheme:
Public UserVO buildUser1(UserDO user) {UserVO vo = new UserVO(); vo.setId(user.getId()); vo.setName(user.getName()); UserAccount account = user.getAccount(); if (Objects.nonNull(account)) { vo.setBalance(account.getBalance()); vo.setDebt(account.getDebt()); } return vo; }Copy the code
The main benefits
- Using temporary variables to clarify logic, business logic is more clear;
- Using temporary variables to simplify the code, see the name of the variable to know its meaning, reduce a lot of useless code;
- If the acquisition function is complicated and time-consuming, using temporary variables can improve the operation efficiency;
- Using temporary variables to avoid cascading function calls can effectively prevent null pointer anomalies.
X. Other details
1. Avoid arbitrary use of static variables
When an object is defined as a static variable, the GC usually does not reclaim the memory occupied by the object, such as
public class A{
private static B b = new B();
}
Copy the code
At this point, the lifetime of the static variable B is synchronized with that of class A. If class A is not unloaded, the b object is resident in memory until the program terminates.
2. Try to avoid creating Java objects too often
Try to avoid in the method called often, cycle of the new object, because the system not only takes time to create the object, but also to spend time to garbage collection and processing of these objects, in we can control the range, maximum reuse objects, best can use object or array to replace basic data type.
3. Use local variables whenever possible
Parameters passed when calling a method and temporary variables created during the call are stored in the Stack, which is faster. Other variables, such as static variables, instance variables, etc., are created in the Heap and are slower.
4. Use synchronized sparingly, minimizing the use of synchronize
It is well known that synchronization is expensive and can even cause deadlocks, so try to avoid unnecessary synchronization control. When the synchronize method is called, it locks the current object so that no other thread can call any other methods on the current object until the method completes execution. Therefore, the synchronize method is kept to a minimum and method synchronization should be used instead of code block synchronization whenever possible.
5. Use primitive data types instead of objects whenever possible
String str = "hello";
Copy the code
This creates a “hello” string, which is cached by the JVM’s character cache pool;
String str = new String("hello");
Copy the code
In addition to creating a String, the String referenced by STR also contains an array of char[], which holds h, E, L, L,o
6. Multithreading should use HashMap and ArrayList as far as possible without thread safety
HashTable, Vector, and so on use synchronization, which degrades performance.
7. Create a HashMap as reasonably as possible
Make full use of this constructor when creating a large hashMap
public HashMap(int initialCapacity, float loadFactor);
Copy the code
By default, initialCapacity is only 16, and loadFactor is 0.75. You’d better be able to accurately estimate the optimal size you need. Vectors do the same thing.
8. Minimize double counting of variables
Such as:
for(int i=0; i<list.size(); i++)Copy the code
Should read:
for(int i=0,len=list.size(); i<len; i++)Copy the code
And avoid using complex expressions in loops, where loop conditions are evaluated repeatedly. If you leave the loop condition values unchanged without using complex expressions, the program will run faster.
9. Avoid unnecessary creation
Such as:
A a = new A();
if(i==1){
list.add(a);
}
Copy the code
Should read:
if(i==1){
A a = new A();
list.add(a);
}
Copy the code
10. Try to free resources in finally blocks
Resources used ina program should be released to avoid resource leaks, preferably ina finally block. Regardless of the result of program execution, the finally block is always executed to ensure that the resource is closed properly.
11. Try to determine the size of the StringBuffer
The constructor of a StringBuffer creates an array of characters of a default size (usually 16). In use, if this size is exceeded, memory is reallocated, a larger array is created, the original array is copied over, and the old array is discarded. In most cases, you can specify the size when creating a StringBuffer so that it doesn’t automatically grow when capacity is low, which improves performance.
Such as:
StringBuffer buffer = new StringBuffer(1000);
Copy the code
12. Release references to useless objects as early as possible
Most of the time, the object referenced by a method’s local reference variable will become garbage as the method terminates, so most of the time the program does not need to explicitly set the local reference variable to NULL.
Such as:
public void test(){ Object obj = new Object(); ... Obj=null; }Copy the code
This one is unnecessary. With the completion of the test() method, the scope of the obJ reference variable in the program ends. But if it is changed to the following:
public void test(){ Object obj = new Object(); ... Obj=null; ... // Execute time-consuming, memory consuming operation; Or call time-consuming, memory consuming methods}Copy the code
It is necessary to set obj to null to release references to Object as soon as possible.
13. Try to avoid using two-dimensional arrays
Two-dimensional data takes up much more memory than a one-dimensional array, perhaps 10 times more.
14. ArrayList & LinkedList
One is a linear list, one is a LinkedList, in short, random queries use ArrayList as much as possible, ArrayList is better than LinkedList, LinkedList also moves Pointers, add and delete operations LinkedList is better than ArrayList, ArrayList also moves data, However, this is a theoretical analysis, the fact is not necessarily so, the important thing is to understand the data structure of the two, appropriate medicine.
15. Try to use system.arrayCopy () instead of looping over arrays
System.arraycopy() is much faster than copying an array through a loop
- public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
SRC: source array; SrcPos: the starting position of the source array to copy; Dest: destination array; DestPos: the starting position of the destination array; Length: indicates the replication length.
public static void main(String[] args) { String[] a = new String[100]; Arrays.fill(a, "hello"); Long start, end, start1, end1; int n = 1000000; int i; int j; start = System.currentTimeMillis(); { String[] b = new String[100]; for (i = 0; i < n; i++) { for (j = 0; j < a.length; j++) { b[j] = a[j]; } } } end = System.currentTimeMillis(); i = 0; start1 = System.currentTimeMillis(); { String[] c = new String[100]; for (i = 0; i < n; i++) { System.arraycopy(a, 0, c, 0, a.length); } } end1 = System.currentTimeMillis(); System.out.println("for loop to copy array 1000000 times takes time: "+ (end-start)); System.out.println(" system.arrayCopy () loop to copy array 1000000 times: "+ (end1-start1)); }Copy the code
The results
For loop to copy array 1000000 times: 161 System.arrayCopy () Loop to copy array 1000000 times: 26Copy the code
16. Reuse objects as much as possible
Excessive object creation will consume a large amount of memory in the system, and in serious cases, will lead to memory leaks. Therefore, it is important to ensure that expired objects are recycled in a timely manner. The JVM’s GC is not very intelligent, so it is recommended that you manually set it to NULL after the object is used.
In the case of strings in particular, use StringBuffer instead of String concatenation because not only will the system spend time generating objects, it may also spend time garbage collecting and processing them later. Therefore, generating too many objects will have a significant impact on the performance of the program.
17. In Java +Oracle application system development, SQL language embedded in Java should be capitalized as far as possible to reduce the parsing burden of Oracle parser.
18. In the Java programming process, database connection, I/O flow operation, after use, timely close to release resources. Because operating on these large objects can cause a lot of overhead.
19. Do not use a Try/Catch statement in a loop. Place the Try/Catch statement in the outermost part of the loop
20. Using the constructor of a StringBuffer to set its initialization capacity can significantly improve performance
The default size of a StringBuffer is 16, and when the StringBuffer reaches its maximum size, it increases itself to twice its current size +2, that is, 2*n+2. Whenever a StringBuffer reaches its maximum capacity, it has to create a new array of objects and then copy the old array of objects, which can waste a lot of time. So it’s important to set the StringBuffer to a reasonable initialization capacity.
21. The StringBuffer and StringBuilder
The difference: java.lang.StringBuffer is a thread-safe mutable character sequence. A String buffer similar to String, but not modifiable. The StringBuilder class should generally be used in preference to this class because it supports all the same operations, but is faster because it does not perform synchronization. For better performance, when constructing a StringBuffer or StringBuilder, try to specify its capacity. Of course not if it’s 16 characters or less. In the same case, using StringBuilder yields only a 10% to 15% performance improvement over using StringBuffer, but at the risk of multithreading insecurity. All things considered, StringBuffer is recommended.
####22. Consider using static methods if there is no need to access the outside of an object, make it static. It is called faster because it does not require a virtual function guide table. This is also a good practice because it tells you how to distinguish the properties of a method that does not change the state of the object.
23. Avoid complex expressions in loop conditions
Without compiler optimization, loop conditions are evaluated repeatedly in loops, and programs run faster if they are left unchanged without complex expressions. Example:
class CEL { void method (Vector vector) { for (int i = 0; i < vector.size (); i++) ; / /... }}Copy the code
Correction:
class CEL_fixed { int size = vector.size () void method (Vector vector) { for (int i = 0; i < size; i++) ; / /... }}Copy the code
24. Define initial sizes for ‘Vectors’ and’ Hashtables’
When the JVM augments a Vector, it recreates a larger array, copies the contents of the original array, and finally reclaims the original array. As you can see, expanding the size of a Vector is a time-consuming process.
In general, the default size of 10 elements is not enough. You’d better be able to accurately estimate the optimal size you need.
public Vector v = new Vector(20);
public Hashtable hash = new Hashtable(10);
Copy the code
25. For constant strings, use ‘String’ instead of ‘StringBuffer’
Constant strings do not need to change their length dynamically.
Example:
StringBuffer s = new StringBuffer ("Hello");
Copy the code
Correction: Replace StringBuffer with String, which will reduce runtime overhead and improve performance if it is certain that the String will not change.
26. Use ‘ ‘instead of “” when adding strings, if the string has only one character
Example:
public void method(String s) {
String string = s + "d";
}
Copy the code
Correction: Replace one character string with ‘ ‘
public void method(String s) {
String string = s + 'd';
}
Copy the code
The above is only part of the Java programming in performance optimization, performance optimization is mostly in terms of time and efficiency, the code structure level of weighing, each have advantages and disadvantages, don’t put the above content as a dogma, perhaps some applicable to our actual work, some do not apply, still hope scenarios are based on the actual work, learning, living accommodation is advisable.