背景
刷算法题的时候,遇到了大佬使用了这个操作,如下:
Map<Character, Integer> map = new HashMap<Character, Integer>(){{
put('-', 1);
put('+', 1);
put('*', 2);
put('/', 2);
put('%', 2);
put('^', 3);
}};
}}
作用是记录运算符的优先级,此类操作还挺常用的。需要注意的是,大佬使用时是将map
作为成员变量放置在方法外的,此时map.put()
操作是无法替代该操作的。
理解
该操作本质上是将一个匿名内部类new HashMap<Character, Integer>(){}
赋值给map
,在匿名内部类内部又使用了一个代码块{}
,因为代码块中可以调用put方法。
匿名内部类是什么?
可参考https://blog.csdn.net/weixin_75202470/article/details/134918960补充基础。
简而言之,就是没有名字,一次性使用的类,但是在JVM层面实际上生成了class文件,所以调用外部变量时需要注意一些事项。此处不涉及调用,所以不展开讨论。
此处的匿名内部类生成后,我们需要调用put方法,在方法外没有办法直接调用方法所以需要使用代码块,也可以理解为是要在构造方法中为成员变量赋值(put
底层原理是为Node<K, V> table
赋值),代码块的意义恰好就是:(1) 相当于另外一种形式的构造器,是对构造器的补充机制,可以做一系列的程序初始化操作;(2) 如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性。最常见的是静态代码块。
class MyClass {
static {
// 优先执行内容
}
{
// 次优先执行内容
}
}
因此,本质上就是使用了匿名内部类new HashMap<Character, Integer>(){}
,再到匿名内部类中加上代码块{}
执行put
方法为成员变量赋值,最后将赋值完的匿名对象赋给最外层的Map<Character, Integer> map
对象。
参考https://www.cnblogs.com/linhan8888/p/16283324.html,https://blog.csdn.net/weixin_43275277/article/details/107023844