java在hashmap初始化时赋初值过程解析

Java中的HashMap是一种常用的数据结构,一般用来做数据字典或者Hash查找的容器。

一般我们初始化并赋初值是这样做的:

HashMap<String, Object> map = new HashMap<>();
map.put("name", "yanggb");
map.put("lover", "huangq");

但是有时候我们会想在一个表达式中完成初始化并赋初值的操作:

HashMap<String, Object> map = new HashMap<>() {
  {
    put("name", "yanggb");
    put("lover", "huangq");
  }
};

这里用了双括号【{{}}】来初始化,使代码简洁易读。第一层括弧实际是定义了一个匿名内部类 (Anonymous Inner Class),第二层括弧实际上是一个实例初始化块 (Instance Initializer Block),这个块在内部匿名类构造时被执行。这种写法的好处很明显,就是一目了然。但是这种写法可能导致这个对象串行化失败的问题。

其一,因为这种方式是匿名内部类的声明方式,所以引用中持有着外部类的引用。所以当串行化这个集合时,外部类也会被不知不觉的串行化,而当外部类没有实现Serialize接口时,就会报错。

其二,在上面的例子中,其实是声明了一个继承自HashMap的子类,然而有些串行化方法,例如要通过Gson串行化为json,或者要串行化为xml时,类库中提供的方式,是无法串行化Hashset或者HashMap的子类的,也就导致了串行化失败。解决办法是重新初始化为一个HashMap对象【new HashMap(map);】,这样就可以正常进行初始化了。

另外要注意的是,这种使用双括号进行初始化的语法在执行效率上要比普通的初始化写法要稍低。

最后,这个使用双括号进行初始化的语法同样适用于ArrayList和Set等集合。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java并发系列之ConcurrentHashMap源码分析

    我们知道哈希表是一种非常高效的数据结构,设计优良的哈希函数可以使其上的增删改查操作达到O(1)级别.Java为我们提供了一个现成的哈希结构,那就是HashMap类,在前面的文章中我曾经介绍过HashMap类,知道它的所有方法都未进行同步,因此在多线程环境中是不安全的.为此,Java为我们提供了另外一个HashTable类,它对于多线程同步的处理非常简单粗暴,那就是在HashMap的基础上对其所有方法都使用synchronized关键字进行加锁.这种方法虽然简单,但导致了一个问题,那就是在同一时间

  • java中ConcurrentHashMap的读操作为什么不需要加锁

    前言 ConcurrentHashMap是Java 5中支持高并发.高吞吐量的线程安全HashMap实现. 我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题--为什么它不需要加锁呢? 下面话不多说了,来一起看看详细的介绍吧 ConcurrentHashMap的简介 我想有基础的同学知道在jdk1.7中是采用Segment + HashEntry + ReentrantLo

  • Java源码解析ConcurrentHashMap的初始化

    首先看一下代码 private final Node<K,V>[] initTable() { Node<K,V>[] tab; int sc; while ((tab = table) == null || tab.length == 0) { // 第一次检查 if ((sc = sizeCtl) < 0) Thread.yield(); // lost initialization race; just spin else if (U.compareAndSwapInt

  • Java HashMap 如何正确遍历并删除元素的方法小结

    (一)HashMap的遍历 HashMap的遍历主要有两种方式: 第一种采用的是foreach模式,适用于不需要修改HashMap内元素的遍历,只需要获取元素的键/值的情况. HashMap<K, V> myHashMap; for (Map.entry<K, V> item : myHashMap.entrySet()){ K key = item.getKey(); V val = item.getValue(); //todo with key and val //WARNI

  • Java中遍历ConcurrentHashMap的四种方式详解

    这篇文章主要介绍了Java中遍历ConcurrentHashMap的四种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方式一:在for-each循环中使用entries来遍历 System.out.println("方式一:在for-each循环中使用entries来遍历");for (Map.Entry<String, String> entry: map.entrySet()) { System.out.pr

  • Java用自定义的类作为HashMap的key值实例

    这是Java中很经典的问题,在面试中也经常被问起.其实很多书或者文章都提到过要重载hashCode()和equals()两个方法才能实现自定义键在HashMap中的查找,但是为什么要这样以及如果不这样做会产生什么后果,好像很少有文章讲到,所以写这么一篇来说明下. 首先,如果我们直接用以下的Person类作为键,存入HashMap中,会发生发生什么情况呢? public class Person { private String id; public Person(String id) { thi

  • Java基础教程之HashMap迭代删除使用方法

    前言 map的迭代删除,和我们常见的list,set不太一样,不能直接获取Iteraotr对象,提供的删除方法也是单个的,根据key进行删除,如果我们有个需求,将map中满足某些条件的元素删除掉,要怎么做呢? I. Map 迭代删除 迭代删除,在不考虑并发安全的前提下,我们看下可以怎么支持 1. 非常不优雅版本 我们知道map并不是继承自Collection接口的,HashMap 也没有提供迭代支持,既然没法直接迭代,那我就老老实的low b版好了 Map<String, Integer> m

  • Java HashMap三种循环遍历方式及其性能对比实例分析

    本文实例讲述了Java HashMap三种循环遍历方式及其性能对比.分享给大家供大家参考,具体如下: HashMap的三种遍历方式 (1)for each map.entrySet() Map<String, String> map = new HashMap<String, String>(); for (Entry<String, String> entry : map.entrySet()) { entry.getKey(); entry.getValue();

  • java在hashmap初始化时赋初值过程解析

    Java中的HashMap是一种常用的数据结构,一般用来做数据字典或者Hash查找的容器. 一般我们初始化并赋初值是这样做的: HashMap<String, Object> map = new HashMap<>(); map.put("name", "yanggb"); map.put("lover", "huangq"); 但是有时候我们会想在一个表达式中完成初始化并赋初值的操作: HashMap

  • java实现上传文件类型检测过程解析

    这篇文章主要介绍了java实现上传文件类型检测过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在进行文件上传时,特别是向普通用户开放文件上传功能时,需要对上传文件的格式进行控制,以防止黑客将病毒脚本上传.单纯的将文件名的类型进行截取的方式非常容易遭到破解,上传者只需要将病毒改换文件名便可以完成上传. 可以读取文件的十六进制的文件头,来判断文件真正的格式. 读取文件的二进制数据并将其转换为十六进制时,同类型文件的文件头数据是相同的,即使改

  • java根据富文本生成pdf文件过程解析

    这篇文章主要介绍了java根据富文本生成pdf文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 public class PdfUtil { /* * 生成pdf工具类 * wmy 12:40 2019/8/9 * @Param [guideBook, pdfPath] * @return java.lang.Boolean **/ public static Boolean htmlToPdf(GuideBook guideBook

  • Java实现简单双色球摇奖功能过程解析

    这篇文章主要介绍了Java实现简单双色球摇奖功能过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 双色球:从1-33号球中选取6个红球,且红球不重复 从1-16号球中选取一个篮球 话不多说 上代码~~~ package Javaee; import java.util.Arrays; import java.util.Random; public class DoubleChromosphere { public static void

  • 使用java NIO及高速缓冲区写入文件过程解析

    这篇文章主要介绍了使用java NIO及高速缓冲区写入文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 byte[] bytes = Files.readAllBytes(Paths.get("E:\\pdf\\aaa\\html\\text.txt").normalize()); String text = IOUtils.toString(bytes); String xml = text.substring(

  • Pycharm debug调试时带参数过程解析

    这篇文章主要介绍了Pycharm debug调试时带参数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天在网上找了一个例子敲代码,因为我使用的是PyCharm,例子运行时需要带参数,开始不知道怎么带参数,网上搜了大半天,最终才找到自己想要的方法,记录一下. 代码中有需要使用到参数,如下图: 因为开始不知道怎么带参数,直接运行时,报错,因为没参数 运行时,至少需要一个文件参数,添加参数 在PyCharm中选择'Run'->Edit C

  • java使用elasticsearch分组进行聚合查询过程解析

    这篇文章主要介绍了java使用elasticsearch分组进行聚合查询过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java连接elasticsearch 进行聚合查询进行相应操作 一:对单个字段进行分组求和 1.表结构图片: 根据任务id分组,分别统计出每个任务id下有多少个文字标题 1.SQL:select id, count(*) as sum from task group by taskid; java ES连接工具类 p

  • Java初始化块及执行过程解析

    问题:Java对象初始化方式主要有哪几种?分别是什么? 针对上面的问题,想必大家脑海中首先浮现出的答案是构造器,没错,构造器是Java中常用的对象初始化方式. 还有一种与构造器作用非常相似的是初始化块,它可以对Java对象进行初始化操作.下面主要阐述Java的初始化块及执行过程. Java初始化块其实是Java类的成员之一,其语法格式如下: [修饰符]{ //初始化块的可执行代码 ... } 初始化块的修饰符只能是static,使用static修饰符的初始化块称为静态初始化块,后面会介绍到. 下

  • Java Elastic Job动态添加任务实现过程解析

    背景 在使用Elastic-Job的过程中,有很多人遇到了这么一个问题,就是如何动态的去添加任务? 在官方的文档中也有对此作出回答,如下: 动态添加作业这个概念每个人理解不尽相同. elastic-job-lite为jar包,由开发或运维人员负责启动.启动时自动向注册中心注册作业信息并进行分布式协调,因此并不需要手工在注册中心填写作业信息. 但注册中心与作业部署机无从属关系,注册中心并不能控制将单点的作业分发至其他作业机,也无法将远程服务器未启动的作业启动.elastic-job-lite并不会

  • Java Validation方法入参校验实现过程解析

    一.前言 在日常的开发中,经常需要对方法参数进行校验(非空.长度等).如果采用hardcode去校验(if..else..),会造成代码冗余,复用性低,导致维护成本比较高.借助Validation组件,可以很方便地通过注解来校验参数. 二.Java Validation组件 JSR JSR 是一种规范标准,规定了一些校验规范的注解,位于javax.validation.constraints包下,只提供规范不提供实现,如@NotNull,@Size 等 Hibernate Validation

随机推荐