红包

此活动已结束。

快过年了,我们来发红包吧。
我把红包隐藏在了这里:
链接: http://pan.baidu.com/s/1bnnj7Cb 密码: r9rr

红包总额不多,希望你能玩得开心。

(提示:在手机版支付宝钱包中输入红包口令就可以拿到红包了。)

Android 5.0 (API 21) 文档下载

因为自带的SDK Manager下载的速度好慢,所以我从度盘里离线下载了下来。
当然,是英文的。

链接:http://pan.baidu.com/s/1o6jxreE 密码:o4qw

原始链接:https://dl-ssl.google.com/android/repository/docs-21_r01.zip

警告:不要将Java中的数组作为Map容器的Key类型

Java语言提供了泛型的支持。你可以将你能想得到的许多种类型作为HashMap等容器的Key类型使用(只要他们正确地实现了hashCode和equals之类的方法)。
你可能会想过把数组类型(例如String[]),作为Map容器的Key使用,例如写出这样的代码:

TreeMap<String[], String> map1;
HashMap<String[], String> map2;

第一行代码根本不能通过编译!这是因为数组类型根本没有实现Comparable接口,无法比较出“大小”,自然使得依赖于树的TreeMap无法工作。
第二行代码不会出现编译问题,但你很快就会发现代码的运行方式会与你所期望的相违背。你可能发现对于具有相同值的两个数组,会被HashMap当作两个不同的Key值,导致相同的Key对应不同的Value,实在是太糟糕了。
出现问题的是数组类型所实现的equals()方法。顾名思义,这个方法比较两个对象是否相等。在这里我们希望作为Key的对象是通过“值”来比较的。也就是说只要两个对象的“值”相同,不管它们是不是同一个对象,就应当认为他们是相等的。
但是与我们所期望的相反,数组类型所实现的equals()方法是基于引用进行比较的,如果两个引用指向的不是同一个对象,即使数组内部元素完全相同,这个方法也会返回false。
所以,请不要把数组作为Map容器的Key类型使用,有一些替代性的方法做参考:

  • 将数组转换为一个字符串。
  • 使用ArrayList,ArrayList中的equals方法是基于值进行比较的。

如果你真的非常想用数组作为Key,你可以考虑自己编写一个类,并正确实现它的equals和hashCode方法。
像这样:

import java.util.Arrays;
public class KeyArray {

    Object[] internalArray;

    KeyArray(Object[] arr) {
        internalArray = arr;
    }

    @Override
    public boolean equals(Object o) {
        /* 谨慎地编写equals方法,这里的代码没有考虑所有的情况 */
        if (o != null) {
            if (o instanceof KeyArray) {
                /* Arrays.equals会对两个数组进行基于值的比较 */
                return Arrays.equals(internalArray, ((KeyArray) o).internalArray);
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        /* Arrays.deepHashCode 会根据数组内的元素的值计算 hashCode */
        return Arrays.deepHashCode(internalArray);
    }
}

之后就可以将KeyArray作为HashMap的Key使用。
最后,我发现了一个很有趣的事情,Java中的List容器是这样计算hashCode的:

int hashCode = 1;
for (E e : list)
      hashCode = 31 * hashCode + (e==null ? 0 : e.hashCode());

我不清楚它使用31这个magic number的理由。如果你有什么想法,可以在评论里告诉我。

修复了Qaptcha插件

我发现了我犯了一个很严重的错误。

把typecho升级到新版以后,原来的Qaptcha不能正常工作。
在没有登录为管理员的情况下,即使按照正常的流程也无法提交评论,并提示验证失败。而登录为管理员以后再提交评论就不会出现这种情况。
由于我一直是以登录状态发送评论的,所以直到别人向我反馈前我都没有发现。
经过检查,我发现新版的typecho似乎在没有登录时不会初始化session,导致无法保存状态信息。
所以我加上了一行session_start以后,就可以解决这个问题。

居然大家都不能评论,而我一直都没有发现,实在是太可怕了。

感谢whitefirer告诉我不能评论的事情。