千家信息网

Java 中HashMap初始化的另一种方式是怎么

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,Java 中HashMap初始化的另一种方式是怎么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。如果你接触过不同的语言,从语法和代码
千家信息网最后更新 2026年11月03日Java 中HashMap初始化的另一种方式是怎么

Java 中HashMap初始化的另一种方式是怎么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

如果你接触过不同的语言,从语法和代码层面来说,Java 是一种不折不扣的"臃肿、啰嗦"的语言,从另一方面来说这种臃肿和啰嗦也体现了它严谨的一面,作为适合构建大型、复杂项目的理由之一。

1、HashMap 初始化的文艺写法

HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器。普通青年一般会这么初始化:

HashMap map = new HashMap();map.put("Name", "June");   map.put("QQ", "2572073701");

看完这段代码,很多人都会觉得这么写太啰嗦了,对此,文艺青年一般这么来了:

HashMap map = new HashMap() {    {        put("Name", "June");           put("QQ", "2572073701");      }};

嗯,看起来优雅了不少,一步到位,一气呵成的赶脚。然后问题来了,有童鞋会问:纳尼?这里的双括号到底什么意思,什么用法呢?哈哈,其实很简单,看看下面的代码你就知道啥意思了。

public class Test {    /*private static HashMap map = new HashMap() {        {            put("Name", "June");            put("QQ", "2572073701");        }    };*/    public Test() {        System.out.println("Constructor called:构造器被调用");    }    static {        System.out.println("Static block called:静态块被调用");    }    {        System.out.println("Instance initializer called:实例初始化块被调用");    }    public static void main(String[] args) {        new Test();        System.out.println("=======================");        new Test();    }}

output:

Static block called:静态块被调用Instance initializer called:实例初始化被调用Constructor called:构造器被调用=======================Instance initializer called:实例初始化被调用Constructor called:构造器被调用

Note:关于 static 的作用与用法如果不了解,请参考:

http://my.oschina.net/leejun2005/blog/193439#OSC_h4_1 为什么 main 方法是 public static void?

http://my.oschina.net/leejun2005/blog/144349#OSC_h4_2 设计模式之:聊聊 java 中的单例模式(Singleton)

也就是说第一层括弧实际是定义了一个匿名内部类 (Anonymous Inner Class),第二层括弧实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。这个块之所以被叫做"实例初始化块"是因为它们被定义在了一个类的实例范围内。
上面代码如果是写在 Test 类中,编译后你会看到会生成 Test$1.class 文件,反编译该文件内容:

D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>jad -p Test$1.class// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://www.kpdus.com/jad.html// Decompiler options: packimports(3)// Source File Name:   Test.javapackage pvuv.zhaopin;import java.util.HashMap;// Referenced classes of package pvuv.zhaopin://            Testclass Test$1 extends HashMap  // 创建了一个 HashMap 的子类{    Test$1()    {                        //  第二个 {} 中的代码放到了构造方法中去了         put("Name", "June");        put("QQ", "2572073701");    }}D:\eclipse_indigo\workspace_home\CDHJobs\bin\pvuv\>

2、推而广之

这种写法,推而广之,在初始化 ArrayList、Set 的时候都可以这么玩,比如你还可以这么玩:

List names = new ArrayList() {    {        for (int i = 0; i < 10; i++) {            add("A" + i);        }    }};System.out.println(names.toString());  // [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9]

3、Java7:增加对 collections 的支持

在 Java 7 中你可以像 Ruby, Perl、Python 一样创建 collections 了。

Note:这些集合是不可变的。

PS:由于原文[5]作者并没有标出 java 7 哪个小版本号引入的这些新特性,对于留言报错的同学,请尝试大于 1.7.0_09 或者 java8 试试?

List list = new ArrayList();list.add("item");String item = list.get(0);Set set = new HashSet();set.add("item");Map map = new HashMap();map.put("key", 1);int value = map.get("key");// 现在你还可以: List list = ["item"];String item = list[0];                Set set = {"item"};                Map map = {"key" : 1};int value = map["key"];

4、文艺写法的潜在问题

文章开头提到的文艺写法的好处很明显就是一目了然。这里来罗列下此种方法的坏处,如果这个对象要串行化,可能会导致串行化失败。
1.此种方式是匿名内部类的声明方式,所以引用中持有着外部类的引用。所以当时串行化这个集合时外部类也会被不知不觉的串行化,当外部类没有实现serialize接口时,就会报错。
2.上例中,其实是声明了一个继承自HashMap的子类。然而有些串行化方法,例如要通过Gson串行化为json,或者要串行化为xml时,类库中提供的方式,是无法串行化Hashset或者HashMap的子类的,从而导致串行化失败。解决办法:重新初始化为一个HashMap对象:

new HashMap(map);

这样就可以正常初始化了。

5、执行效率问题

当一种新的工具或者写法出现时,猿们都会来一句:性能怎么样?(这和男生谈论妹纸第一句一般都是:"长得咋样?三围多少?"一个道理:))
关于这个两种写法我这边笔记本上测试文艺写法、普通写法分别创建 10,000,000 个 Map 的结果是 1217、1064,相差 13%。

public class Test {    public static void main(String[] args) {        long st = System.currentTimeMillis();        /*        for (int i = 0; i < 10000000; i++) {            HashMap map = new HashMap() {                {                    put("Name", "June");                    put("QQ", "2572073701");                }            };        }        System.out.println(System.currentTimeMillis() - st); // 1217        */        for (int i = 0; i < 10000000; i++) {            HashMap map = new HashMap();            map.put("Name", "June");            map.put("QQ", "2572073701");        }        System.out.println(System.currentTimeMillis() - st); // 1064    }}

6、由实例初始化块联想到的一些变量初始化问题

从代码上看,a 为什么可以不先声明类型?你觉得 a、b、c 的值分别是多少?能说明理由么?

TIPS:如果你对这块机制不了解,建议试着反编译一下字节码文件。

6.1 测试源码
public class Test {        int e = 6;    Test() {        int c = 1;        this.f = 5;        int e = 66;    }    int f = 55;    int c = 11;    int b = 1;    {        a = 3;        b = 22;    }    int a = 33;    static {        d = 4;    }    static int d = 44;        int g = 7;    int h = 8;    public int test(){        g = 77;        int h = 88;        System.out.println("h - 成员变量:" + this.h);        System.out.println("h - 局部变量: " + h);        return g;    }    public static void main(String[] args) {        System.out.println("a: " + new Test().a);        System.out.println("b: " + new Test().b);        System.out.println("c: " + new Test().c);        System.out.println("d: " + new Test().d);        System.out.println("f: " + new Test().f);        System.out.println("e: " + new Test().e);        System.out.println("g: " + new Test().test());    }}
6.2 字节码反编译:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://www.kpdus.com/jad.html// Decompiler options: packimports(3)// Source File Name:   Test.javaimport java.io.PrintStream;public class Test{    Test()    {        this.e = 6;        f = 55;        this.c = 11;        b = 1;        a = 3;        b = 22;        a = 33;        g = 7;        h = 8;        int c = 1;        f = 5;        int e = 66;    }    public int test()    {        g = 77;        int h = 88;        System.out.println((new StringBuilder("h - \u6210\u5458\u53D8\u91CF\uFF1A")).append(this.h).toString());        System.out.println((new StringBuilder("h - \u5C40\u90E8\u53D8\u91CF: ")).append(h).toString());        return g;    }    public static void main(String args[])    {        System.out.println((new StringBuilder("a: ")).append((new Test()).a).toString());        System.out.println((new StringBuilder("b: ")).append((new Test()).b).toString());        System.out.println((new StringBuilder("c: ")).append((new Test()).c).toString());        new Test();        System.out.println((new StringBuilder("d: ")).append(d).toString());        System.out.println((new StringBuilder("f: ")).append((new Test()).f).toString());        System.out.println((new StringBuilder("e: ")).append((new Test()).e).toString());        System.out.println((new StringBuilder("g: ")).append((new Test()).test()).toString());    }    int e;    int f;    int c;    int b;    int a;    static int d = 4;    int g;    int h;    static    {        d = 44;    }}
6.3 output:
a: 33b: 22c: 11d: 44f: 5e: 6h - 成员变量:8h - 局部变量: 88g: 77

关于Java 中HashMap初始化的另一种方式是怎么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

写法 实例 问题 代码 方式 变量 文艺 方法 编译 子类 文件 构造器 普通 臃肿 推而广之 内容 字节 实际 对象 局部 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 高科技互联网 广州百单互联网科技有限公司 重生之互联网科技帝国 科技赋能下的互联网金融 科技和互联网公司 科技互联网政务服务 互联网科技有限公司图片 有木互联网科技 滨湖区互联网智能科技产品供应 互联网科技公司招聘 济南和联互联网科技有限公司 重庆威客帮互联网科技 互联网金融科技公司干啥的 浙江互联网科技研学营 宜昌元轩互联网科技有限公司 电子商务与互联网科技的关系 杭州披云加互联网科技有限公司 厦门江牛科技互联网 普陀区互联网教育科技管理办法 众联互联网络科技 互联网科技公司简介 互联网科技革命 厦门千工互联网科技有限公司 互联网公司黑科技创始人 中天科技中国工业互联网 陕西云淼互联网科技公司 科技互联网行业投资研究 中国科技和美国互联网 瑞安市蟠桃会互联网科技有限公司 高科技和互联网的现代国家
0