iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java 中HashMap初始化的另一种方式是怎么
  • 673
分享到

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

2023-06-19 10:06:41 673人浏览 独家记忆
摘要

Java 中HashMap初始化的另一种方式是怎么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。如果你接触过不同的语言,从语法和代码层面来说,Java 是一种不折不扣的“臃

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

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

1、HashMap 初始化的文艺写法

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

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

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

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

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

public class Test {        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<String> names = new ArrayList<String>() {    {        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<String> list = new ArrayList<String>();list.add("item");String item = list.get(0);Set<String> set = new HashSet<String>();set.add("item");Map<String, Integer> map = new HashMap<String, Integer>();map.put("key", 1);int value = map.get("key");// 现在你还可以: List<String> list = ["item"];String item = list[0];Set<String> set = {"item"};Map<String, Integer> 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<String, String> map = new HashMap<String, String>();            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初始化的另一种方式是怎么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网精选频道了解更多相关知识。

--结束END--

本文标题: Java 中HashMap初始化的另一种方式是怎么

本文链接: https://www.lsjlt.com/news/295467.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java 中HashMap初始化的另一种方式是怎么
    Java 中HashMap初始化的另一种方式是怎么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。如果你接触过不同的语言,从语法和代码层面来说,Java 是一种不折不扣的“臃...
    99+
    2023-06-19
  • Java中HashMap的初始容量设置方式
    Java中HashMap的初始容量设置 根据阿里巴巴Java开发手册上建议HashMap初始化时设置已知的大小,如果不超过16个,那么设置成默认大小16: 集合初始化时, 指定集合初...
    99+
    2024-04-02
  • hashmap初始化直接赋值的方法是什么
    在Java中,可以使用如下方法直接初始化一个HashMap并赋值: Map<String, Integer> map =...
    99+
    2024-03-11
    hashmap
  • Java中初始化List集合的八种方式汇总
    目录1、常规方式2、Arrays 工具类3、Collections 工具类4、Lists 工具类5、匿名内部类6、ImmutableList7、Java8 Stream8、Java9...
    99+
    2024-04-02
  • 数组的三种初始化方式
    1. 直接初始化:在声明数组的同时给出初始值,例如:`int[] arr = {1, 2, 3, 4, 5};` 这种方式适用于已知...
    99+
    2023-09-01
    数组
  • java中的数组初始化赋初值方式
    目录java数组初始化赋初值方法一方法二方法三数组互相赋值方式使用for循环使用Object的clone()使用System的静态方法arraycopy()java数组初始化赋初值 ...
    99+
    2024-04-02
  • java中double初始化的方法是什么
    在Java中,可以使用以下方法来初始化一个double变量: 1、直接赋值: double num = 10.5; 2、使用构造器...
    99+
    2024-04-02
  • Java中ArrayList初始化的四种方法详解
    目录1 起因2 解决方案2.1 双括号法2.2 Arrays.asList2.3 stream2.4 Lists3 总结1 起因 在实际业务开发中, 我们经常会遇到需要临时创建一个数...
    99+
    2024-04-02
  • Java中ArrayList初始化的四种方法的介绍
    本篇内容主要讲解“Java中ArrayList初始化的四种方法的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中ArrayList初始化的四种方法的介绍”吧!1 起因在实际业务开发中...
    99+
    2023-06-14
  • C++类成员初始化的三种方式
    目录一、初始化方式1、初始化方式一:初始化列表2、初始化方式二:构造函数初始化3、初始化方式三:声明时初始化(也称就地初始化,c++11后支持)二、声明时初始化->初始化列表-...
    99+
    2024-04-02
  • Win10怎样初始化电脑?Win10初始化电脑的方式
    当电脑初始化系统软件后操作系统会复原到刚安裝情况并清理数据文档,也就是等同于将电脑恢复到刚选购时的情况。那麼Win10应当怎样初始化电脑呢?还不清楚具体步骤的小伙伴们,可以参照下列实际操作哦,期待对你有些协助。Win10初始化电脑的方式:最...
    99+
    2023-07-14
  • c++数组初始化的方式有哪几种
    C++数组可以使用以下几种方式进行初始化:1. 使用花括号{}初始化:cppint arr1[] = {1, 2, 3, 4, 5}...
    99+
    2023-10-18
    c++
  • java变量的初始化方法是什么
    Java变量的初始化方法有以下几种:1. 声明变量时直接赋值:可以在声明变量时直接为其赋初值,例如:```javaint num =...
    99+
    2023-09-15
    java
  • java中Map和List初始化的N种方法总结
    目录Map和List初始化方法第一种方法(常用方法)第二种方法(双括号初始化法)第三种,stream初始化初始化Map和List小技巧(指定容量+匿名内部类初始化)总结Map和Lis...
    99+
    2023-03-22
    java中Map初始化 java中List初始化 Map和List初始化方法
  • java初始化数组的方法是什么
    Java中初始化数组有以下几种方法:1. 静态初始化:在声明数组的同时直接为数组元素赋值。```javaint[] arr = {1...
    99+
    2023-08-29
    java
  • Java中怎么实现初始化
    Java中怎么实现初始化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、静态块优先程序首先会执行静态块的内容,这也就有了不写main方法就跑hello wor...
    99+
    2023-06-17
  • java怎么初始化一个空数组
    在Java中,可以使用以下方法来初始化一个空数组:1. 使用`new`关键字和数组类型的构造函数来创建一个指定大小的空数组。例如,要...
    99+
    2023-08-15
    java
  • java数组初始化的方式有哪些
    Java数组可以通过以下几种方式进行初始化:1. 静态初始化:在声明数组的同时为数组元素赋初值。```javaint[] arr =...
    99+
    2023-09-09
    java
  • Java初始化与清除的方法是什么
    本篇内容介绍了“Java初始化与清除的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!对象的创建与初始化是同一个概念,不能分离2、构...
    99+
    2023-06-03
  • java静态map初始化的方法是什么
    在Java中,静态Map可以通过静态代码块或静态方法进行初始化。1. 使用静态代码块:```javapublic class MyC...
    99+
    2023-10-12
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作