java ImmutableMap的使用说明

ImmutableMap:一个不可变集合

java中的Immutable对象:

简单地说,如果一个对象实例不能被更改就是一个Immutable的对象,Java SDK提供的大量值对象,比如String等都是Immutable的对象。

创建ImmutableMap:

Map<String,Object> immutableMap = new ImmutableMap.Builder<String,Object>().build();

在创建时放值:

Map<String,Object> immutableMap = new ImmutableMap.Builder<String,Object>()
    .put("k1","v1")
    .put("k2","v2")
    .build();

创建后不可变:

immutableMap.put("k1","v3");//会抛出java.lang.UnsupportedOperationException

ImmutableMap中key和value均不能为null,放入null值会抛出NPE

ImmutableMap的使用场景:

适合

1、确定性的配置, 比如根据不同的key值得到不同的请求url

2、写单元测试

不适合

1、key, value为未知参数, 可能有null产生的情况

guava中ImmutableMap使用示例及好处

ImmutableMap是不可变的,线程安全的;它可以创建一些常量的映射键值对;他提供了很多的组合键值对的方法,源码中使用了一个静态内部类来组装构建ImmutableMap,静态内部类作为外部类的辅助构建ImmutableMap,内部使用final声明了一个ArrayList变量。

public static class Builder<K, V>{
     final ArrayList<Map.Entry<K, V>> entries = Lists.newArrayList();
    public Builder() {}
    public Builder<K, V> put(K key, V value)
    {
      this.entries.add(ImmutableMap.entryOf(key, value));
      return this;
    }
    public Builder<K, V> put(Map.Entry<? extends K, ? extends V> entry)
    {
      K key = entry.getKey();
      V value = entry.getValue();
      if ((entry instanceof ImmutableEntry)) {
        Preconditions.checkNotNull(key);
        Preconditions.checkNotNull(value);
        Map.Entry<K, V> immutableEntry = entry;
        this.entries.add(immutableEntry);
      }
      else
      {
        this.entries.add(ImmutableMap.entryOf(key, value));
      }
      return this;
    }
    public Builder<K, V> putAll(Map<? extends K, ? extends V> map)
    {
      this.entries.ensureCapacity(this.entries.size() + map.size());
      for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
        put(entry.getKey(), entry.getValue());
      }
      return this;
    }
    public ImmutableMap<K, V> build()
    {
      return fromEntryList(this.entries);
    }
    private static <K, V> ImmutableMap<K, V> fromEntryList(List<Map.Entry<K, V>> entries)
    {
      int size = entries.size();
      switch (size) {
      case 0:
        return ImmutableMap.of();
      case 1:
        return new SingletonImmutableBiMap((Map.Entry)Iterables.getOnlyElement(entries));
      }
      Map.Entry<?, ?>[] entryArray = (Map.Entry[])entries.toArray(new Map.Entry[entries.size()]);
      return new RegularImmutableMap(entryArray);
    }
  }

之前我们判断取值结果可以使用if else形式:

int a = 1;
        if(a == 1) {
            System.out.println(a);
        } else {
            System.out.println(a);
        }

或者使用switch方式:

 int a = 1;
        switch (a) {
        case 1:
            System.out.println(a);
            break;
        case 2:
            System.out.println(a);
        default:
            System.out.println(a);
            break;
        }

现在可以使用ImmutableMap集合来组装键值对,这样的组合方式既简单又省去了大量多余的代码:

ImmutableMap<String, Object> map = ImmutableMap .<String, Object>builder()
         .put("1", "1")
         .put("2", "2")
         .put("3", "3")
         .build();
ImmutableMap<String, String> map1 = ImmutableMap .<String, String>of("1", "2");

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2021-06-08

JAVA不可变类(immutable)机制与String的不可变性(推荐)

一.不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值.如JDK内部自带的很多不可变类:Interger.Long和String等. 可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类. 二.不可变类的优点 说完可变类和不可变类的区别,我们需要进一步了解为什么要有不可变类?这样的特性对JAVA来说带来怎样的好处? 1.线程安全 不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因

Java中如何实现不可变Map详解

前言 有时最好不允许修改  java.util.Map, 例如跨线程共享只读数据.为此,我们可以使用Unmodifiable Map或Immutable Map. 在这个快速教程中,我们将看到它们之间的区别.然后,我们将介绍可以创建不可变Map的各种方法. 下面话不多说了,来一起看看详细的介绍吧 不可修改与不可变 Unmodifiable Map其实是一个可以修改的map的包装器,不允许直接修改它. Map<String, String> mutableMap = new HashMap<

解决启动Azkaban报错问题:java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap

问题描述: 启动Azkaban报错: java.lang.NoSuchMethodError:com.google.common.collect.ImmutableMap.toImmutableMap 解决方法: 从报错信息来看,是找不到toImmutableMap这个方法.首先找到类ImmutableMap对应的Jar包为guava,然后在服务器查找这个Jar包: find / -name "guava*.jar" 发现除了Azkaban安装目录,其他程序目录下也有guava包.Az

快速解决VS Code报错:Java 11 or more recent is required to run. Please download and install a recent JDK

VS Code确实不是最好的Java编译器(好吧,它或许都不该算是个编译器),在使用的过程完全依赖咱们自己写一些配置或者使用一些插件,但是因为它外观好看,我还是比较喜欢用这个.哪怕遇到的问题比别的编译器多得多.排查错误原因的过程中也能学到不少东西. 近期遇到这个问题,每次打开VS Code的时候,右下角会弹出一个弹框,上面写着: Java 11 or more recent is required to run. Please download and install a recent JDK.

Tomcat启动时报错:java.lang.UnsatisfiedLinkError的解决

问题 之前tomcat启动老是报错,虽然不影响项目的启动运行,但是有强迫症的程序员会心里不爽: 如下: 问题分析 由于本机安装的jdk版本与tomcat中使用的jdk版本不一致导致的. 解决方法 后面我把原先tomcat启动环境用的jdk1.7改为了本机安装的jdk1.8就不在报错. 具体过程: 在myeclipse中点击window→preference→在搜索框中输入Tomcat→选择安装的tomcat版本,我这里是选择Tomcat 7.x→点击JDK→在Tomcat 7.x JDK nam

解决idea导入ssm项目启动tomcat报错404的问题

用idea写ssm项目,基于之前一直在用spring boot 对于idea如何运行ssm花费了一番功夫 启动Tom act一直在报404 我搜了网上各种解决办法都不行,花费一天多的时间解决不了 就是在pom中添加下面代码 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin<

解决Maven 项目报错 java.httpservlet和synchronized使用方法

使用java8 的lanmbe表达式时,使用java1.8编译,则会报错 需要在pom.xml的<bulid></build>中添加 <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</versi

django启动uwsgi报错的解决方法

uwsgi介绍 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI / uwsgi / uWSGI 这三个概念的区分. WSGI是一种Web服务器网关接口.它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信. 而u

解决 java.lang.NoSuchMethodError的错误

解决 java.lang.NoSuchMethodError的错误 1 原因 在项目依赖比较复杂或者 Java 运行的环境有问题时,或者同一类型的 jar 包有不同版本存在,都可能触发该错误.本质上说是 JVM 找不到某个类的特定方法,也就是说 JVM 加载了错误版本的类.说白了,就是 JVM 找不到真正想要调用的方法啦!出现该错误的情形主要有以下两个种: 导入了不匹配的包版本: 开发环境和运行环境不一致. 2 解决方法 查看"External Libraries",看报错的方法到底存

Azkaban报错-azkaban.executor.ExecutorManagerException: No active executors found

Issue 2019/05/09 21:50:07.380 +0800 ERROR [ExecutorManager] [Azkaban] No active executors found 2019/05/09 21:50:07.380 +0800 ERROR [StdOutErrRedirect] [Azkaban] Exception in thread "main" 2019/05/09 21:50:07.380 +0800 ERROR [StdOutErrRedirect]

ECSHOP完美解决Deprecated: preg_replace()报错的问题

随着PHP5.5 的普及,ECSHOP系统又爆出了新的错误.PHP发展到PHP5.5版本以后,有了很多细微的变化.而ECSHOP官方更新又太慢,发现这些问题后也不及时升级,导致用户安装使用过程中错误百出.说了半天,这个新错误到底是什么呢,它的完整错误提示信息是这样的: Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in....... 注意:不是所有人的ECS

解决Unixbench安装报错信息的问题

运行环境: Ubuntu 16.04.3 x86_64 在Ubuntu下安装运行Unixbench时,提示报错信息如下 gcc -o ./pgms/ubgears -DTIME -Wall -pedantic -ansi -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall ./src/ubgears.c -lGL -lXext -lX11 /usr/bin/ld: /tmp/ccnTgDEZ.o: undefined reference