Ten coding tips about Java

I believe that everyone likes to look at concise and easy-to-understand code. Code readability is also one of the important criteria for measuring code quality. This article uses ten specific programming tips (some of them are not limited to Java), hoping to help you.

1. Use ternary expressions

Consider the following code:

public boolean isOdd(int num) {
    
    
    if (num % 2 == 1) {
    
    
        return true;
    } else {
    
    
        return false;
    }
}

We may often see code similar to the above, which only requires a simple if ... else ...judgment, and the content of the judgment is also very simple. At this time, we can use ternary expressions to simplify our code, as shown below such:

public boolean isOdd(int num) {
    
    
	return num % 2 == 1 ? true : false;
}

It can be found that by using ... ? ... : ...ternary expressions, we can write simpler code. Of course, this code is still not concise enough. We will discuss the second point below. Here we will discuss ternary expressions first. Although the ternary expression can simplify our code, and in many cases, it can also simplify our code, but when there are too many judgments and the statement is long, we should not use ternary expressions, like the following In this case, we should not use ternary expressions:

public int getMaxDays(int year, int month) {
    
    
    // 当条件过多时, 使用三元表示就无法体现发挥简洁的优势了,我们应该考虑其它的方法
    return month == 2 ? (isLeapYear(year) ? 29 : 28) :
            (month == 4 || month == 6 || month == 9 || month == 11) ? 30 : 31;
}

private boolean isLeapYear(int year) {
    
    
    return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}

2. Simplify Boolean conditional expressions

Consider again the code in 1:

public boolean isOdd(int num) {
    
    
	return num % 2 == 1 ? true : false;
}

Since the result we return is a boolean value, in this case, we can directly return the boolean expression without the need for conditional judgments, making the code not concise:

public boolean isOdd(int num) {
    
    
	return num % 2 == 1;
}

3. Use guard sentences

In 1 we used a counter-example to explain that the ternary means do not need to be changed and used indiscriminately. Here we first use the ifstatement to rewrite and write the first version of the code:

public int getMaxDays(int year, int month) {
    
    
    int result;
    if (month == 2) {
    
    
        result = isLeapYear(year) ? 29 : 28;
    } else if (month == 4 || month == 6 || month == 9 || month == 11) {
    
    
        result = 30;
    } else {
    
    
        result = 31;
    }
    return result;
}

private boolean isLeapYear(int year) {
    
    
    return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ;
}

In order to implement the 单入口单出口principle, we make multiple judgments dependent. If there are a large number of statements in each judgment condition, it will show the disadvantages of this writing method. Therefore, for this situation, we usually write 单入口多出口code , So that simple situations can be judged as soon as possible, without coupling between each judgment sentence:

public int getMaxDays(int year, int month) {
    
    
    if (month == 2) {
    
    
        return isLeapYear(year) ? 29 : 28;
    } 
    if (month == 4 || month == 6 || month == 9 || month == 11) {
    
    
        return  30;
    }
    return 31;
}

private boolean isLeapYear(int year) {
    
    
    return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}

4. Use arraycopyCopy Array

We may sometimes need to make a copy of the original array because we cannot modify the original array, and then write code similar to the following:

int[] arr = {
    
    1, 2, 3, 4, 5};
int[] temp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
    
    
    temp[i] = arr[i];
}

However, we can arraycopymake the code more readable and more efficient by using the functions that come with the system :

int[] arr = {
    
    1, 2, 3, 4, 5};
int[] temp = new int[arr.length];
System.arraycopy(arr, 0, temp, 0, arr.length);

5. Use try ... with ...for resource management

When using iostreams, because we need to manage resources, we need to write code similar to the following. When multiple resources need to be managed, it is not only difficult to manage, but we may often forget to close the resources:

FileInputStream fis = null;
try {
    
    
	fis = new FileInputStream(new File(""));
	fis.read();
} catch (Exception e) {
    
    
	e.printStackTrace();
} finally {
    
    
	try {
    
    
		fis.close();
	} catch (IOException e) {
    
    
		e.printStackTrace();
	}
}

But by using try ... with ...it, you can write the following simple code, we don't need to worry about resource management issues:

try (FileInputStream fis = new FileInputStream(new File(""))) {
    
    
	fis.read();
} catch (Exception e) {
    
    
	e.printStackTrace();
}

6. Bit arithmetic tips

I believe many people know that bit operations can show better performance in many cases, and in some cases can also simplify the code. Here are two small examples:

  1. Use displacement instead of multiplication and division:

    a << n // <=> a * 2^n
    a >> n // <=> a / 2^n
    
  2. Use bit operations to avoid addition overflow in dichotomy:

    I believe many people know that in binary search, the following code may not get the correct result due to the overflow of the addition operation:

    int mid = (left + right) / 2;
    

    It can be avoided if you use the following method:

    int mid = left + (right - left) / 2;
    

    But by using unsigned displacement, we can write the following concise code, and also avoid overflow:

    int mid = (left + right) >>> 1;
    
  3. Determine whether the two numbers are the same number

    If you don't use bit operations, we need to write the following code:

    (a >= 0 && b >= 0) || (a < 0 && b < 0)
    

    But if we use ^the features, we can write the following concise code:

    (a ^ b) >= 0
    

7. Split string

In many cases, in order to print and debug, we need to divide and print the data or strings of the array, such as the format of printing [1, 2, 3]or "123"printing 1, 2, 3. According to the traditional way, we need to write the following code:

int[] arr = {
    
    1, 2, 3};
StringBuilder sb = new StringBuilder(String.valueOf(arr[0]));
for (int i = 1; i < arr.length; i++) {
    
    
    sb.append(", ").append(arr[i]);
}
// output: 1, 2, 3
System.out.println(sb);

String str = "123";
String[] split = Pattern.compile("").split(str);
StringBuilder sb = new StringBuilder(split[0]);
for (int i = 1; i < split.length; i++) {
    
    
    sb.append(", ").append(split[i]);
}
// output: 1, 2, 3
System.out.println(sb);

But by using Streamthe characteristics, we can write the following more convenient and readable code (for code readability, we usually split the chain call into multiple lines):

int[] arr = {
    
    1, 2, 3};
// output: 1, 2, 3
System.out.println(
        IntStream.of(arr)
                 .mapToObj(String::valueOf)
                 .collect(Collectors.joining(", "))
);

String str = "123";
// output: 1, 2, 3
System.out.println(
        Pattern.compile("")
               .splitAsStream(str)
               .collect(Collectors.joining(", "))
);

8. Use system method to print array

We usually need to print the array for debugging, as mentioned in 7, but we usually only need to be able to get the data of the array, and don’t care about its form, but if we print the array directly, we will only get a memory address, but we actually We can Arrays.toString(arr)easily achieve our needs by calling :

int[] arr = {
    
    1, 2, 3};
// output: [1, 2, 3]
System.out.println(Arrays.toString(arr));

9. StreamImplement the counter

Sometimes, we need to count the number of data in an array or collection, we will write the following code:

int[] arr = {
    
    1, 2, 3, 4, 5, 6};
Map<Integer, Integer> map = new HashMap<>();
for (int val : arr) {
    
    
    map.put(val, map.getOrDefault(val, 0) + 1);
}

If Streamwe use it , we can focus more on our business logic, and it can also be easier to read:

int[] arr = {
    
    1, 2, 3, 4, 5, 6};
Map<Integer, Integer> map = IntStream.of(arr)
                                     .boxed()
                                     .collect(Collectors.toMap(k -> k, k -> 1, Integer::sum));

10. Use to Arrays.asList(arr)convert an array of objects to a collection

Sometimes we need to write code similar to the following in order to convert the array to a collection:

String[] strs = new String[10];
List<String> list = new ArrayList<>();
for (String str : strs) {
    list.add(str);
}

But using Array.asList(arr)it, you can write the following concise code:

String[] strs = new String[10];
// Array.asList(arr)生成的结果集合无法进行数据的修改,因此需要使用 new ArrayList<>();
List<String> list = new ArrayList<>(Arrays.asList(strs));

Or use Streamthis to convert:

String[] strs = new String[10];
List<String> list = Stream.of(strs).collect(Collectors.toList());

The above is about Javasome programming tips, I hope to be of some help to you.

Guess you like

Origin blog.csdn.net/qq_41698074/article/details/108688146