Algorithm
链表相交
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode cur1 = headA;
ListNode cur2 = headB;
int n = 0;
while (cur1.next != null) {
n++;
cur1 = cur1.next;
}
while (cur2.next != null) {
n--;
cur2 = cur2.next;
}
if (cur1 != cur2) {
return null;
}
cur1 = n > 0 ? headA : headB;
cur2 = cur1 == headA ? headB : headA;
n = Math.abs(n);
while (n != 0) {
n--;
cur1 = cur1.next;
}
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
}
Review
Why we should stop using data binding in Android
这个文章和我的观点相同hhh
Tip
工作中使用 try catch 捕获异常,被同事提 comment 要求使用 runCatching,了解一下:
runCatching是Kotlin 1.3版本引进的一个异常处理函数,其作用是让代码块内的异常不会中断代码的执行,在发生异常时可以捕获异常并返回一个结果或者进行错误处理。
runCatching函数通过lambda表达式接收一个需要处理异常的代码块(可以返回任何类型的值),如果代码块中出现了异常,runCatching会捕获异常并返回一个包装了异常的Result对象(Result.Success或Result.Failure),我们可以通过该对象进行异常的处理。
fun divide(a: Int, b: Int): Result<Int> {
return runCatching {
a / b
}
}
在上面的例子中,divide函数通过runCatching捕获了可能会抛出ArithmeticException异常的代码块,在该代码块中,如果b的值为0,那么会抛出ArithmeticException异常,但是这并不会中断代码的执行,代码会继续执行并将异常封装成Result.Failure返回。
如果代码块中没有出现任何异常,则runCatching会将代码块的返回值封装成Result.Success返回。
我们可以通过getOrElse方法从Result对象中获取异常处理后的值:
val result = divide(10, 2)
val value = result.getOrElse {
// 处理异常,设置默认值
-1
}
上面的代码中,getOrElse方法会检查result对象是否为Result.Success,如果是的话会返回正常的值,否则返回我们指定的默认值(在lambda表达式中)。
需要注意的是,runCatching函数只能处理代码块中的异常,如果代码块中抛出了RuntimeException或Error等非受检异常,则在异常发生时代码会立即终止。
Share
本周通读了《计算机是怎样跑起来的》和《程序是怎样跑起来的》的前五章。