不含常规的快捷键
最常用快捷键

1.Ctrl+E,可以显示最近编辑的文件列表
2.Shift+Click 可以关闭文件
3.Ctrl+[或]可以跳到大括号的开头结尾
4.Ctrl+Shift+Backspace可以跳转到上次编辑的地方
5.Ctrl+F12 可以显示当前文件的结构
6.Ctrl+F7可以查询当前元素在当前文件中的引用,然后按F3可以选择
7.Ctrl+N,可以快速打开类
8.Ctrl+Shift+N,可以快速打开文件
9.Alt+Q可以看到当前方法的声明
10.Ctrl+W可以选择单词继而语句继而行继而函数
11.Alt+F1可以将正在编辑的元素在各个面板中定位
12.Ctrl+P,可以显示参数信息
13.Ctrl+Shift+Insert可以选择剪贴板内容并插入
14.Alt+Insert可以生成构造器/Getter/Setter等
15.Ctrl+Alt+V 可以引入变量。例如把括号内的SQL赋成一个变量
16.Ctrl+Alt+T可以把代码包在一块内,例如try/catch
17.Alt+Up and Alt+Down可在方法间快速移动
18.Ctrl+Alt+ left/right 返回至上次浏览的位置
19.Alt+ left/right 切换代码视图
20.Ctrl+Shift+Up/Down 代码向上/下移动。
21.F2 或Shift+F2 高亮错误或警告快速定位

当快捷键不起作用时,看看是不是跟别的软件的快捷键冲突了。

先看代码:

public class MySeed {
    public static void main(String[] args) {
        Random random=new Random(100);
        for(int i=0;i<5;i++){
            System.out.println(new Random(100).nextInt(9999));
        }
        System.out.println("===============");
        for(int i=0;i<5;i++){
            System.out.println(random.nextInt(9999));
        }
    }
}

输出:
8980
8980
8980
8980
8980
===============
8980
4033
9748
9720
7576
解释:
用一个固定的种子值来生成的随机数的值是有固定序列的。
1、第一个for中每次一个新Random对象,这个对象生成的第一个随机数始终为8980.
2、第二个for中使用一个对象,生成5个随机数,随机数的值和顺序也是固定的。
这段代码无论执行多少次,得到的值都是一样。

所以在取随机数时,种子应该是动态的。一般建议不传种子,那也就是使用new Random()。

public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

private static long seedUniquifier() {
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

网上的一段对随机数的解读:
根c/C++类似,所有标准库提供的Random函数其实都是假Random,真正的Random函数式不需要Seed的。
所谓假Random,是指所返回的随机数字其实是一个稳定算法所得出的稳定结果序列,而不是真正意义上的随机序列。 Seed就是这个算法开始计算的第一个值。所以就会出现只要seed是一样的,那么后续所有“随机”结果和顺序也都是完全一致的。 通常情况下,你可以用 DateTime.Now.Millisecend() 也就是当前始终的毫秒来做Seed .因为毫秒对你来说是一个1000以内的随即数字。 这样可以大大改善保准库的Random结果的随机性。 不过这仍然算不上是完全随机,因为重复的概率还是千分之一。

另外需要注意的是,如果一直调用标准库Random,那么在调用了N次以后,输出结果就会循环最开始的序列了。也就是说,标准库Random所能生成的不同结果的个数也是有限的。32位系统一般也就是几万次以后就会出现重复。

https://social.msdn.microsoft.com/Forums/zh-CN/77ce649a-7fc5-4d17-94d7-d4f8be8e5ad8/randomseed?forum=visualcshartzhchs

支持继承验证,注解到父类上,验证子类是没有问题的。

NotNull 可注解到任意对象,Integer上是可以的,而NotEmpty只能注解到字符串上。

Min可以注解到Integer上,但如果参数为null,则不会处理。

所以要验证Integer,Double,Long型,要加上NotNull和Min两个注解。

为何Min注解不能直接判断是否为Null呢?这使多少开发人员都得掉进坑里。

如果出现javax.validation.UnexpectedTypeException: No validator could be found for type: java.lang.Integer
这类错误,注意看是否将NotEmpty注解到Integer上了。

原有项目无法启动junit测试,经过几番调整后,剔除了重复引用的多版本spring后,aop冲突解决了,测试junit没问题。

第二天再用junit测试,报这个错误。

java.lang.NoClassDefFoundError: org/junit/runner/Describable

Google之,junit4.4升级至4.5即可。可能跟easymock有关系。

easymock好用吗?不觉得使用,写代码量太大,用法学习成本也很高。

当junit报错找不到placeholder时,可以maven package一下。

定义:向下传递事件的模式即责任链模式。

1、事件类拥有共同的父类Event。
2、事件处理的类都要共同实现一个事件接口方法,方法参数为共同的事件父类。
3、事件处理类中含有下一级的事件处理类实例字段,定义为接口类型;
4、事件处理类的接口方法中通过instanceof判断是否本类处理,如果不是调用下一级的事件类来处理。

核心:某个接口的实现类中有这个接口的另一个实现类属性(字段),if not, field do same thing (invoke the same method)。

public class Event {
}
public class OneDayRestEvent extends Event {
}
public class TwoDayRestEvent extends Event {
}
public class FiveDayRestEvent extends Event {
}
public interface EventHandler {
    void handle(Event event);
}
public class LeaderEventHandler implements EventHandler{
    private EventHandler eventHandler;
    public LeaderEventHandler(EventHandler eventHandler){
        this.eventHandler=eventHandler;
    }
    @Override
    public void handle(Event event) {
        if(event instanceof OneDayRestEvent){
            System.out.println("do leaderEvent");
        }else{
            eventHandler.handle(event);
        }
    }
}
public class ManagerEventHandler implements EventHandler {
    private EventHandler eventHandler;
    public ManagerEventHandler(EventHandler eventHandler){
        this.eventHandler=eventHandler;
    }
    @Override
    public void handle(Event event) {
        if(event instanceof TwoDayRestEvent){
            System.out.println("do managerEvent");
        }else{
            eventHandler.handle(event);
        }
    }
}
public class DirectorEventHandler implements EventHandler {

    @Override
    public void handle(Event event) {
        System.out.println("do directorEvent");
    }
}
public class Test {
    public static void main(String[] args) {
        FiveDayRestEvent fiveDayRestEvent=new FiveDayRestEvent();
        OneDayRestEvent oneDayRestEvent=new OneDayRestEvent();
        TwoDayRestEvent twoDayRestEvent=new TwoDayRestEvent();

        EventHandler directorEventHandler=new DirectorEventHandler();
        //在链条中经理向下传递给总监
        EventHandler managerEventHandler=new ManagerEventHandler(directorEventHandler);
        //在链条中主管向下传递给经理
        EventHandler leaderEventHandler=new LeaderEventHandler(managerEventHandler);

        leaderEventHandler.handle(oneDayRestEvent);
        leaderEventHandler.handle(twoDayRestEvent);
        leaderEventHandler.handle(fiveDayRestEvent);
        System.out.println("=====================");
        managerEventHandler.handle(twoDayRestEvent);
        managerEventHandler.handle(fiveDayRestEvent);
        System.out.println("=====================");
        directorEventHandler.handle(fiveDayRestEvent);
    }
}

例:一天假只需组长审批,两天到五天假经理审批,五天以上总监审批。
这只是一种理论上的模式,真正应用时还需要增加很多逻辑来控制业务上责任链规则,比如如何判断是否本类执行,可能是instanceof判断,也可能设计个审批层级,大于某个level,manager处理等。

最近使用的会移至尾部,LinkedHashMap输出时其元素是有顺序的,HashMap是无序的,因为hashMap没有双向链表,只是根据hashcode的值决定存储在数组中哪个位置;

LinkedHashMap可以作为LRU的一个实现,自带核心方法 removeEldestEntry(),默认返回false。

自己可以继承这个类,重写 removeEldestEntry方法,当put时,会调用。

一般场景,当map.size()>maxCapacity 时,返回true,意味着在put时会移除掉最老的那个。