Writer:BYSocket(泥沙砖瓦浆木匠)

微博:BYSocket

豆瓣:BYSocket

Java 容器的文章这次应该是最后一篇了:Java 容器 系列。 今天泥瓦匠聊下 Maps。

一、Map回顾

Map,又称映射表,是将键映射到值的对象。有四种实现Map接口并且经常使用的Map集合为:HashMap,TreeMap,Hashtable 和 LinkedHashMap.

泥瓦匠记忆宫殿:

1、一个映射不包含重复的键

2、每个键最多只能映射到一个值。

二、HashMap

HashMap是基于哈希表的Map接口的实现。其对键进行散列,散列函数只能作用于键。下面模拟下,公司员工和找员工的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.HashMap;
import java.util.Map;
 
class Employee
{}
 
public class HaspMap01
{
    public static void main(String[] args)
    {
        Map<String, Employee> employees = new HashMap<String, Employee>();
        employees.put("1206010035", new Employee());
        System.out.println(employees);
         
        String number = "1206010035";
        System.out.println(employees.get(number));
    }
}

Run一下,大家可以见到结果:put方法,可以将键值映射添加进表。get方法则返回指定键所映射的值。从他们 hashCode 可以看出是同一个对象。

HaspMap的键必须唯一,同样其同一个键不能存放两个值,如果对同一个键两次调用put方法,第二个值会取代第一个值。同样是允许使用 null 值和 null 键。下面泥瓦匠用一个简单的例子解释下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package javaBasic.collection.map;
 
import java.util.HashMap;
import java.util.Map;
 
 
public class HaspMap02
{
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String[] args)
    {
        Map map = new HashMap<String, String>();
        map.put(null, "null01");
        map.put(null, "null02");
        System.out.println(map);
        System.out.println(map.get(null));
    }
}

结果如下:

1
2
{null=null02}
null02

由此可见,第一个值被第二个值所替换了。

下面有三点是HashMap重要之处:

1、HashMap的构造函数

   HaspMap构造函数涉及两个参数:初始容量和加载因子。初试容量是哈希表创建时的其中桶的含量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。这两个参数都是影响HashMap的性能。默认构造一个具有默认初始容量 (16) 和默认加载因子 (0.75)。默认加载因子 (.75) 在时间和空间成本上是一种折衷的考虑。

2、和上次总结的Set都差不多,这个HashMap线程是不安全不同步的。如果想防止意外发生,则设置成同步即可:

1
Map m = Collections.synchronizedMap(new HashMap(...));

3、不同步的话,意味着存在快速失败导致的并发修改异常。

下面看一个复杂例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package javaBasic.collection.map;
 
import java.util.HashMap;
import java.util.Map.Entry;
 
class A
{
    public boolean equals(Object obj)
    {
        return true;
    }
}
 
class B
{
    public int hashCode()
    {
        return 1;
    }
}
 
class C
{
    public int hashCode()
    {
        return 2;
    }
 
    public boolean equals(Object obj)
    {
        return true;
    }
}
 
public class HashMap03
{
    public static void main(String[] args)
    {
        HashMap<A, Integer> hashMapA = new HashMap<A, Integer>();
        hashMapA.put(new A(), 10);
        hashMapA.put(new A(), 5);
         
        System.out.println("HashMapA Elements:");
        System.out.print("\t" + hashMapA + "\n");
         
        // loop HashMapA
        for(Entry<A, Integer> entryA : hashMapA.entrySet())
        {
            System.out.println(entryA.getKey().toString()+"-"+entryA.getValue());
        }
         
        HashMap<B, Integer> hashMapB = new HashMap<B, Integer>();
        hashMapB.put(new B(), 10);
        hashMapB.put(new B(), 5);
         
        System.out.println("HashMapB Elements:");
        System.out.print("\t" + hashMapB + "\n");
         
        // loop HashMapB
        for(Entry<B, Integer> entryB : hashMapB.entrySet())
        {
            System.out.println(entryB.getKey().toString()+"-"+entryB.getValue());
        }
         
        HashMap<C, Integer> hashMapC = new HashMap<C, Integer>();
        hashMapC.put(new C(), 10);
        hashMapC.put(new C(), 5);
         
        System.out.println("HashMapC Elements:");
        System.out.print("\t" + hashMapC + "\n");
         
        // loop HashMap
        for(Entry<C, Integer> entryC : hashMapC.entrySet())
        {
            System.out.println(entryC.getKey().toString()+"-"+entryC.getValue());
        }
    }
}

运行一下,可以看到以下结果:

 

由此可见,其中和 Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较 中涉及的知识点一致:

集合判断两个元素相等不单单是equals方法,并且必须hashCode()方法返回值也要相等。


三、TreeMap

    TreeMap使用树结构实现(红黑树),集合中的元素进行排序,但是添加、删除和包含的算法复杂度为O(log(n))。其实Map特性基本都是一致的,比如看下面的简单例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class TreeMap01
{  
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args)
    {
        Map map = new TreeMap();
        map.put("1", "1");
        map.put("4", "4");
        map.put("2", "2");
        map.put("2", "3");
        System.out.println(map);
    }
}

结果如下:

1
{1=1, 2=3, 4=4}

从中我们可以看出

1、TreeMap实现了SortedMap,顾名思义,其表示为有排序的集合。

2、同样其同一个键不能存放两个值,如果对同一个键两次调用put方法,第二个值会取代第一个值。

四、总结

HashMap与TreeMap
1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。HashMap中元素的排列顺序是不固定的)。
2、  HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。
3、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。 这个TreeMap没有调优选项,因为该树总处于平衡状态。

Writer:BYSocket(泥沙砖瓦浆木匠)

微博:BYSocket

豆瓣:BYSocket

Java 容器 & 泛型:五、HashMap 和 TreeMap的自白的更多相关文章

  1. Java 容器 & 泛型:一、认识容器

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 容器是Java语言学习中重要的一部分.泥瓦匠我的感觉是刚开始挺难学的,但等你熟悉它,接触多了,也就“顺 ...

  2. Java 对比Hashtable、Hashmap、Treemap有什么不同?

    ①基本理解 Hashtable.Hashmap.Treemap都是最常见的一些Map实现,是以键值对的形式存储和操作数据的容器类型. Hashtable是Java类库提供的一个哈希实现,本身是同步的, ...

  3. Java 容器源码分析之 TreeMap

    TreeMap 是一种基于红黑树实现的 Key-Value 结构.在使用集合视图在 HashMap 中迭代时,是不能保证迭代顺序的: LinkedHashMap 使用了双向链表,保证按照插入顺序或者访 ...

  4. java面试题之HashMap和TreeMap的区别

    HashMap和TreeMap的区别 相同点: 都是以key和value的形式存储: key不可以重复: 都是线程不安全的: 不同点: HashMap的key可以为空 TreeMap的key值是有序的 ...

  5. Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等

    /* Map集合:该集合存储键值对.一对一对往里存.而且要保证键的唯一性. Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低.基本已废 ...

  6. Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 上一篇总结了下ArrayList .LinkedList和Vector比较,今天泥瓦匠总结下Hash ...

  7. java容器三:HashMap源码解析

    前言:Map接口 map是一个存储键值对的集合,实现了Map接口的主要类有以下几种 TreeMap:用红黑树实现 HashMap:数组和链表实现 HashTable:与HashMap类似,但是线程安全 ...

  8. Java 容器 & 泛型:六、容器讲到为什么要使用泛型

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket ArrayList是集合类中无处不在的,泛型也是,泛型对集合类尤其有用.但是为啥要使用泛型?理解好了这 ...

  9. Java 容器 & 泛型:四、Colletions.sort 和 Arrays.sort 的算法

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 本来准备讲 Map集合 ,还是喜欢学到哪里总结吧.最近面试期准备准备,我是一员,成功被阿里在线笔试秒杀 ...

随机推荐

  1. e.stopPropagation()兼容性处理

    使用jquery库,e.stopPropagation()兼容所有. 原生的就要这么写 function stopPropagation(e){ e=window.event||e; if(docum ...

  2. Python从入门到精通之Second!

    初识Python基础! -基础     -扩展名可以是任意的,但是导入模块时,如果不是.py文件就会报错. -两种执行方式      1.python解释器       文件名.py 文件路径 -Li ...

  3. P3805 【模板】manacher算法

    #include <bits/stdc++.h> #define up(i,l,r) for(register int i = (l);i <= (r); i++) #define ...

  4. 与我们息息相关的internet服务(2)---WWW服务

    在起步一个公司,从组建的技术上,可能要准备很多东西,其中一个就是我们熟悉的公司网站    网站,在初中,那时浏览一个网页可叫网上冲浪,听起来似乎比洗澡还爽快,可现在这词就是土鳖,网上冲浪火起来主要是应 ...

  5. maven + eclipse + tomcat热部署 引自:http://jingpin.jikexueyuan.com/article/23068.html

    方案二: 1.修改tomcat的server.xml配置文件,在host结点下添加如下代码 Xml代码   <Context docBase="F:\eclipse_workspace ...

  6. java解析json数据用到的jar包

    百度云连接: https://pan.baidu.com/s/1iuQCc7uBO5XtAsNn6hwCew

  7. 学习Python第六天

    今天我们讲讲数据类型中的集合,博客写得有点糙,后续应该要进行优化优化了........ 集合:无序,不重复的数据组合,主要作用:去重,把一个列表变成集合,就自动去重了 基本语法:S = {1}类型为集 ...

  8. Eclipse下用NDK编译生成so文件

      我们在安装环境的时候安装了NDK,可以在eclipse下直接生成so文件.NDK的压缩包里面自带了一些sample工程,NDK的文件直接解压到某个目录下即可. 第一次生成so文件的时候,我们先使用 ...

  9. 《python语言程序设计》_第二章笔记之2.13_软件开发流程

    #程序1: 设计:由用户键入利率.贷款数以及贷款的年限,系统计算出每月还贷数和总还款数 注意:输入的年利率是带有百分比的数字,例如:4.5%.程序需要将它除以100转换成小数.因为一年有12个月,所以 ...

  10. (一)Javascript 面向对象编程:封装

    Javascript 面向对象编程:封装 作者:阮一峰 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP ...