小h陪我俩年多了,饱经沧桑与折磨,却依然不离不弃~ 看着身边不少朋友都加入了hhkb阵营,倍感欣慰…hahaha
因为是白色版本,易脏,非常不易洗,在2014过去之前给它好好洗个澡吧,这也是它的第二个「澡」

  1. 拔键帽,试用过市面上常用的几种拔键器,貌似不太好拔,原因不明。换成原厂的拔键器后则轻松很多,如图:
    hhkb-clean-1.jpg
    不要看这个键盘挺干净,其实是洗完后拍的,忘记把它的脏样子留下来了~
    拆卸的时候注意下每排键帽的高度不同,别到装得时候开始惆怅了。拆卸空格键的时候要小心下面的那颗弹簧,很容易飞出去~

  2. 拆下的键帽可机洗,可手洗,第一次我试用机洗「扔洗衣机」,效果非常好~ 但总觉得会对键帽造成一定磨损,这次索性就手洗了,目测效果比机洗差一个等级。键帽的材质是pbt,不易出油,但不清楚洗涤液对它的腐蚀性如何。
    底座的清洗方式只能动用小刷子和Cyber Clean了,效果也不错。
    洗完拍个全家福,预祝2015年「阖家欢乐」:
    hhkb-clean-2.jpg

本文大部分内容翻译自一篇Git好文(原文地址),经过我拙劣的英文加上自定义的删减与修改~ 也作为Git系列的开头篇

Interactive stage

你也许经常会遇到在对一个文件的多次不同的修改,并且在提交的时候常犹豫哪一段修改是需要commit,这时你可以使用:

git add/commit -p <FILE>

加上 -p 参数之后,git会一块一块的显示出差异,确认当前块是否需要暂存。这样你可以提交文件中的部分修改,还可以使用 -i 参数,更为详细的交互式界面。

ps: 使用交互式的提交不仅能让Commit更加的准确,还可以对代码进行一次很好的review,是值得养成的一个好习惯

Checkout Your Last Branch

当你正忙碌的工作在当前分支下,此时有紧急需求需要对之前的主分支做一些修改,
这时候常用的操作流:

git stash
git checkout develop
//修改提交后 ...commit..push..
git checkout xxx
git stash pop

你可能觉得这样很繁琐乏味,你需要这样的操作:

git checkout -
//切换到develop分支 ...commit...push
git checkout -

这样可以快速切换分支,只能切换到当前分支的上一级母分支,和*NIX的 cd - 类似。

Show Which Branches are Merged (or not)

工作中经常同时工作于多个分支之上,一个项目的feature分支会非常的多,可以通过 branch --list/-l 看到,常遇到情况是,当想清理分支的时候心理还带着一丝犹豫,担心这个分支是否合并到主分支过,或者经常忘记哪些分支合并过,哪些没有。一般情况下都去查看pr记录,或者检查commit信息。
那你可能需要是以下的操作:

git branch --no-merged

可以查看有哪些分支还没有合并到当前的分支, 当然也可以查看哪些已经合并过:

git branch --merged

并且还可以配合一些简单的UNIX工具来执行迅速的删除操作,像这样:

git branch --merged | xargs git branch -d

Grab a File from Another Branch without Switching Branches

当你在做一些类似重构的工作时,你可能需要从多个分支中取出不同的几个修改纳入到当前的分支来。
如果没有下面的提示,你可能进行的操作是:

while(true){
  stash 当前修改
  切换分支
  找出修改的部分,copy到临时文件
  checkout -
  粘贴到该修改的地方
}

或者你可以进行简单的文件迁移工作:

git checkout <BRANCH> -- path/to/file.rb
eg: 
#把tmp分支的 .gitignore 修改迁移到本分支
git checkout tmp -- ./.gitignore

注意,这里是整个文件的覆盖,并不是合并。

Git Branches Sorted by Last Commit

你应该已经看到了本地的一大堆杂乱的分支,并且使用之前的 --merged 清理过其中一些分支了,那对于剩下的分支,该如何确定哪些是有用的,哪些是过时的呢?

for-each-ref 命令会输出每个分支列表,并且显示最后一次的提交信息。重要的是,我们还可以对列表进行日期的排序,以下命令会显示整个分支列表以及最后一次提交信息和提交者,并且按日期降序排序。

//这是原版
git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) [%(committername)]'
//原版并没有输出commit时的message,以下是我个人使用的改良版
git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) "%(subject)" [%(committername)]'

建议给它取一个别名,方便日后使用。

git config --global alias.latest "for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) "%(subject)" [%(committername)]'"

Java中对对象的集合或数组进行排序时通常有两种方式:Comparator && Comparable。

Comparable要求使用对象实现其compareTo方法来实现自定义的排序方式。
但在使用的场景中,往往在设计时并没有考虑到比较问题从而没有实现Comparable,这时候再去改造对象本身或许不太合适。

Comparator更加的灵活,采用的是策略模式,在不改变对象本身的情况下来改变对象的行为
举例说明:

class User {
    //年龄
    private Integer age;
    //身高
    private Integer height;
    //姓名
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

现在需要给所有的User对象按年龄从小到大排序,如果年龄相同则按身高由高到低来排序。
以下是Comparable方式,通过改造User对象来实现自定义compileTo方法:

class User implements Comparable<User>{
    //年龄
    private Integer age;
    //身高
    private Integer height;
    //姓名
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(User u) {
        int flag = this.age.compareTo(u.getAge());
        if (flag == 0 ) {
            return (this.height.compareTo(u.getHeight())) * -1;
        } else {
            return flag;
        }
    }
}

以下是Comparator的实现方法及测试类:

public class Test {
    public static void main(String[] args) {

        User user1 = new User();
        user1.setAge(20);
        user1.setHeight(180);
        user1.setName("张三");
        User user2 = new User();
        user2.setAge(20);
        user2.setHeight(176);
        user2.setName("李四");
        User user3 = new User();
        user3.setAge(25);
        user3.setHeight(155);
        user3.setName("王二");
        User user4 = new User();
        user4.setAge(23);
        user4.setHeight(155);
        user4.setName("麻子");
        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        //使用Comparator实现排序
        Collections.sort(userList, new Comparator<User>() {
            @Override
            public int compare(User u1, User u2) {
                int flag = u1.getAge().compareTo(u2.getAge());
                if (flag == 0) {
                    //身高降序
                    return (u1.getHeight().compareTo(u2.getHeight())) * -1;
                } else {
                    return flag;
                }
            }

        });

        //如果使用Comparable方式,可直接使用以下方式排序即可
        Collections.sort(userList);

        for (User u : userList) {
            System.out.println("姓名:"+u.getName()+",年龄:"+u.getAge()+",身高:"+u.getHeight());
        }

    }

}

结果:

姓名:张三,年龄:20,身高:180
姓名:李四,年龄:20,身高:176
姓名:麻子,年龄:23,身高:155
姓名:王二,年龄:25,身高:155

达到的效果一致,但是,这并没有结束。
在Java规范里,倡导保证equals和compareTo的行为一致,这样可以避免出现一些奇奇怪怪的问题。大致意思就是如果user1.compareTo(user2) == 0 的话,user1.equals(user2) == 1
既然重载了equals,那意味着hashcode也得重载了~ 你懂的