关于Java的十个编码小技巧

相信每个人都喜欢看简洁易懂的代码,代码可读性也是衡量代码质量的重要标准之一,而本文则通过十个具体的编程小技巧(部分技巧并不局限于Java),希望能够帮助到你。

1. 使用三元表达式

考虑以下代码:

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

我们可能会经常见到类似上面的代码,只需要一次简单的if ... else ...判断,而判断所得到的内容也很简单,在这种时候,我们就可以使用三元表达式来简化我们的代码,就像下面这样:

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

可以发现,通过使用... ? ... : ...三元表达式,我们能够写出更加简单的代码,当然这个代码仍然不够简洁,在接下来第二点会进行讨论,这里先讨论三元表示式。虽然三元表示式可以简化我们的代码,在很多时候也能够简化我们的代码,但是当判断的情况过多并且语句较长的时候,我们就不应该使用三元表达式了,就像下面这种情况,我们就不应该采用三元表达式:

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. 简化布尔条件表达式

再次考虑1中的代码:

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

由于我们返回的结果是布尔值,所以在这种情况下,我们就可以直接返回布尔表达式即可,而不需要再进行条件判断,让代码不够简洁:

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

3. 使用卫语句

在1中我们以一个反例讲诉了三元表示不用改被乱用,这里我们就先通过if语句,来进行改写,写出第一版代码:

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) ;
}

我们为了实现单入口单出口原则,而让多次判断都有依赖,如果每个判断条件内存在大量的语句的时候,更会显示出这种编写方式的弊端,因此对于这种情况,我们通常会编写单入口多出口的代码,让简便情况尽快得到判断,每个判断语句之间不必耦合:

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. 使用arraycopy拷贝数组

我们有时可能因为不能在原数组上进行修改,需要对原数组进行一份拷贝,然后写出类似下面这样的代码:

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];
}

不过我们可以通过使用系统自带的arraycopy函数,让代码更易读,效率也更高:

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

5. 使用try ... with ...进行资源管理

当使用io流时,我们由于需要对资源进行管理,需要写出类似下面的代码,当多个资源需要管理的时候,不仅难以管理,我们还可能经常会忘记对资源的关闭:

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();
}
}

但是通过使用try ... with ...就可以写出下面这样简便的代码,我们不需要再担心资源的管理问题:

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

6. 位运算小技巧

相信很多人都知道,位运算在很多情况下都能表现出更好地性能,在某些情况下也能够简化代码,这里就讲两个小例子:

    使用位移代替乘除法:

    a << n // <=> a * 2^n
    a >> n // <=> a / 2^n

    使用位运算避免二分法中的加法溢出:

    相信很多人都知道在二分查找中,以下代码可能因为加法运算的溢出,导致无法得到正确的结果:

    int mid = (left + right) / 2;

    如果使用下面这种方法就可以避免:

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

    但是通过使用无符号位移,我们就可以写出下面这样简洁的代码,而且也可以避免溢出:

    int mid = (left + right) >>> 1;

    判断两号是否同号

    如果不使用位运算,我们需要写出下面这样的代码:

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

    但是如果使用^的特性,我们就可以写出下面这样简洁的代码:

    (a ^ b) >= 0

7. 分割字符串

很多时候,我们为了进行打印调试,都需要对数组的数据或者字符串进行分割打印,例如将[1, 2, 3]或者"123"打印为1, 2, 3的格式,按照传统的方式,我们需要写出下面这样的代码:

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);

但是通过使用Stream的特性,我们就能写出下面这样更加方便易读的代码(为了代码的可读性,我们通常会将链式调用拆成多行):

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. 使用系统方法打印数组

我们通常需要打印数组进行调试,正如7中所说的那样,但是我们通常只要能够得出数组的数据即可,而不在乎其形式,但是如果直接打印数组,只会得到一个内存地址,不过我们其实可以通过调用Arrays.toString(arr),很容易就实现我们的需求:

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

9. Stream实现计数器

有时,我们需要对数组或者集合中的数据进行统计其次数,我们会写出如下所示的代码:

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);
}

如果利用Stream,我们就能够更加专注于我们的业务逻辑,也可加易读:

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. 使用Arrays.asList(arr)将对象数组转换为集合

有时我们需要为了将数组转换为集合,然后写出类似下面的代码:

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

但是利用Array.asList(arr)就可以写出下面这样简洁的代码:

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

或者使用Stream这样进行转换:

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

以上就是关于Java的一些编程小技巧,希望能够对你有些帮助。

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

关于Java的十个编码小技巧

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 关于Java的十个编码小技巧
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏