Map

Map中的key和value为Object类型数据,会封装到HashMap$Node对象中
Map中key不可以重复,但value可以重复
当添加相同key的数据时,value会替换原来的value
Map中key可以为null,value也可以为null,但key为null只能有一个,value为null可以有多个
常用String类作为Map的key

 

put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中

Object remove(Object key):移除指定key的key-value对,并返回value

void clear():清空当前map中的所有数据

get(Object key):根据指定的键,在Map集合中获取对应的值

containsKey(Object key):判断集合中是否包含指定的键

常用方法:

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System

 

 

 

Map的6大遍历方式

通过keySet()方法

Map map = new HashMap();
map.put(1,1);
map.put(2,2);
map.put(3,3);
//使用增强for循环先取出所有的key,再通过key取出对应的value
Set keyset = map.keySet();
for(Object key : keyset) {
	System.out.println(key + "-" +map.get(key));
}
//使用迭代器取出所有key-value
Iterator iterator = keyset.iterator();
while(iterator.hasNext()) {
	Object key = iterator.next();
	System.out.println(key + "-" +map.get(key));
}

  

通过values()方法获取所有value,不能获取key

Map map = new HashMap();
map.put(1,1);
map.put(2,2);
map.put(3,3);

Collection values = map.values();
//1、使用增强for循环取出所有value
//2、使用迭代器取出所有value

  

通过entrySet()方法

Map map = new HashMap();
map.put(1,1);
map.put(2,2);
map.put(3,3);

Set entrySet = map.entrySet();     //EntrySet<Map.Entry<K,V>>
//使用增强for循环进行遍历
for(Object entry : entrySet) {
	//将 entry 转换为 Map.Entry
	Map.Entry m = (Map.Entry) entry;
	System.out.println(m.getKey() + "-" +  m.getValue());
}
//使用迭代器
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()) {
	Object entry = iterator.next();
	Map.Entry m = (Map.Entry) entry;
	System.out.println(m.getKey() + "-" +  m.getValue());
}

  

HashMap

HashMap是Map接口使用频率最高的实现类
HashMap是线程不安全的

 

HashMap源码解析

HashMap构造器

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_02

HashMap成员变量

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_03

 

 

无参构造器,创建对象时,将加载因子(loadFactor)初始化为 0.75

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_04

 

初始化table容量大小为指定值 initialCapacity,并初始化加载因子(loadFactor)为 0.75

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_构造器_05

 

将table容量和加载因子(loadFactor)都初始化为指定值

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_06

 

 

添加key-value时,通过key的哈希值进一步处理得到在table上的索引。然后判断该索引处是否有元素,如果没有元素则直接添加;如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等,如果相等则直接替换value,如果不相等需要判断是树结构还是链表结构,做出相应处理

 

Hashtable

Hashtable的key和value都不能为null
Hashtable是线程安全的

当添加相同key的数据时,value会替换原来的value

 

Hashtable源码解析

Hashtable构造器

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_07

Hashtable成员变量

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_08

 

 

最终都是调用同一个构造器

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_构造器_09

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_10

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_11

 

 

存储数据的table

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_12

 

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_13

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_14

 

 

扩容机制

(oldCapacity << 1) + 1  即 oldCapacity*2+1

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_15

 

 

Properties

Properties类继承Hashtable类
Properties可以使用键值对的形式保存数据,还可以用于从 xxx.properties 文件中加载数据到Properties类对象,并进行读取和修改

Properties源码解析

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_构造器_16

 

 

 

 

 

TreeMap

TreeMap

TreeMap源码解析

TreeMap构造器

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_17

TreeMap成员变量

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_18

 

 

当使用的key实现了Comparable接口时,使用TreeMap的无参构造器即可实现排序功能

当使用的key没有实现Comparable接口时,可以通过传递匿名类实现的Comparator比较器来实现排序功能

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_构造器_19

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_System_20

 

 

Entry是TreeMap中结点的类型

 

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_21

LinkedHashMap循环判断 java 删除数据 java判断map的value是否重复_初始化_22

 

 

TreeMap的put方法

public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }