A
描述: 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
思路: 从 m 到 n 阶段的反转的实现和反转整个链表的思路是一样的。但是需要保存起始时m-1和m位置的结点,用来在最后将链表连接为1个整体。
R
Safe Parsing Kotlin Data-classes with Gson
问题
如下的数据类:
data class SomeData(
val intValue: Int,
val strValue: String = "default value"
)
默认值将会被忽略,如 {"intValue":2}
的 json 会生成对象 {intValue=2,srtValue=null}
而不是 {intValue=2,srtValue="default"}
解决方法
解决方法是为所有属性都添加上默认值,如:
data class SomeData(
val intValue: Int = 0,
val strValue: String = "default value"
)
原因
1. Kotlin 数据类的字节码不同
两个类的字节码如下:
public final class WithoutDefaultConstructor {
private final int intValue;
@NotNull
private final String strValue;
public WithoutDefaultConstructor(int intValue, @NotNull String strValue) {
super();
this.intValue = intValue;
this.strValue = strValue;
}
public WithoutDefaultConstructor(int intValue, String strValue, int defaultParametersFlags, DefaultConstructorMarker defaultConstructorMarker) {
if ((defaultParametersFlags & 2) != 0) {
strValue = "default";
}
this(intValue, strValue);
}
//... other methods
}
public final class WithDefaultConstructor {
private final int intValue;
@NotNull
private final String strValue;
public WithDefaultConstructor(int intValue, @NotNull String strValue) {
super();
this.intValue = intValue;
this.strValue = strValue;
}
public WithDefaultConstructor(int intValue, String strValue, int defaultParametersFlags, DefaultConstructorMarker defaultConstructorMarker) {
if ((defaultParametersFlags & 1) != 0) { // checking binary flag for the first parameter presence `01`
intValue = 1;
}
if ((defaultParametersFlags & 2) != 0) { // checking binary flag for the second parameter presence `10`
strValue = "default";
}
this(intValue, strValue);
}
public WithDefaultConstructor() {
this(0, (String)null, 3, (DefaultConstructorMarker)null);
}
//... other methods
}
当所有参数都有默认值时,编译器会自动为其生成默认无参的构造函数。
2. Java 在 Gson 中的不安全调用
默认构造函数在 Gson
中很重要。其工作方式大致如下:
- 尝试通过基于 type-token 的 InstanceCreator 来创建对象。
- 尝试调用默认构造函数。
- 尝试为 maps,sets,queues 等调用已知的构造函数。
- 如果都不起效,则会使用 unsafe allocation 。
这意味着,如果没有 instance creator ,并且类没有默认构造函数,会在不调用构造函数的情况下创建对象。而 Kotlin 将所有非空检查和默认值的分配都放在构造函数中,在这种情况下,它们将都会被跳过。
T
Python 浮点数的一个冷知识
- 包含 float('nan') 的两个元组,当作整体比较时相等,但其对位的元素可能不相等。
- float('nan') 表示一个“不是数”的东西,本身是个不确定值,两个对象做比较时不相等,但其哈希值是固定的,作比较值时相等。用作字典的键值时是不冲突的。
- float('inf') 表示无穷大的浮点数,可看作是确定值,两个对象作比较时相等,哈希结果也相等。但用作字典值时冲突。
- float('nan') 的哈希结果为 0 ,float('inf') 的哈希结果为 314159
S
无