Map:
- 双列数据,存储key-value对的数据 ----->类似于函数y=f(x)
- Map结构的理解:
1、Map中的key:无序的,不可重复的,使用Set存储所有的key ----->key所在的类要重写equals()和hashCode()(以HashMap为例)
2、Map中的value:无序的、可重复的,使用Collection存储所有的value ----->value所在的类要重写equals()
3、一个键值对:key-value构成了一个Entry对象
4、Map中的entry:无序的、不可重复的,使用Set存储所有的entry - Map常用方法:添加、删除、修改、查询、长度、遍历(注意:没有插入)
import org.junit.Test;
import java.util.*;
public class MapTest {
@Test
public void test1(){
Map map = new HashMap();
//添加
map.put("AA",123);
map.put(123,123);
map.put("BB",456);
//修改:覆盖原数据
map.put("AA",456);
System.out.println(map);//{AA=456, BB=456, 123=123}
Map map1 = new HashMap();
map1.put("CC",1);
map1.put("DD",2);
//putAll(Map map1)
map.putAll(map1);
System.out.println(map);//{AA=456, BB=456, CC=1, DD=2, 123=123}
//remove()
Object value = map.remove("CC");
System.out.println(value);//1:"CC"对应的值
System.out.println(map);//{AA=456, BB=456, DD=2, 123=123}
//clear():把value清空
map.clear();
System.out.println(map.size());//0
System.out.println(map);//{}
}
@Test
public void test2(){
Map map = new HashMap();
map.put("AA",123);
map.put(123,123);
map.put("BB",456);
//Object get(Object key)
System.out.println( map.get("AA"));//123
//boolean containsKey(Object key)
boolean isExist = map.containsKey("BB");
System.out.println(isExist);//true
//boolean containsValue(Object value)
boolean isExist1 = map.containsValue(123);//key为:"AA",123,所对应的value都为123,找到一个就不再找下去
System.out.println(isExist1);//true
//isEmpty()
map.clear();
System.out.println(map.isEmpty());//true
//equals
Map map1 = new HashMap();
map1.put("A",1);
Map map2 = new HashMap();
map2.put("A",1);
System.out.println(map1.equals(map2));//true
}
@Test
public void test3() {
Map map = new HashMap();
map.put("AA",123);
map.put(123,123);
map.put("BB",456);
//遍历所有key集:keySet()
Set set = map.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next() );//"AA","BB",123
}
//遍历所有的value:values()
Collection values = map.values();
Iterator iterator1 = values.iterator();
while (iterator1.hasNext()){
System.out.println(iterator1.next());//123,456,123
}
//遍历所有key-value:
// 方式一:entrySet()
Set entrySet = map.entrySet();//entrySet是一个Set类型,其中存放的数据类型是Entry
Iterator iterator2 = entrySet.iterator();
while (iterator2.hasNext()){
Object obj = iterator2.next();
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey());//"AA","BB",123
}
//方式二:使用getKey()得到key,再调用get
Set keySet = map.keySet();
Iterator iterator3 = keySet.iterator();
while (iterator3.hasNext()){
Object key = iterator3.next();
Object value = map.get(key);
System.out.println(value);//123,456,123
}
}
}
HashMap:
- 作为Map的主要实现类,线程不安全,效率高,可以存储null的key和value
- HashMap的底层原理(以jdk7为例)
在实例化以后,底层创建了长度是16的一维数组Entry[] table
map.put(key1,value1)//在此之前可能已经执行过多次put
首先,调动key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
如果此位置上的数据为空,此时的key1-value1添加成功
如果此位置上的数据不为空(意味着此位置上存在一个或多个数据),比较key1和已经存在的一个或多个数据的哈希值:
----如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功
----如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals()方法,比较:
--------如果equals()返回false:此时key1-value1添加成功
--------如果equals()返回true:使用value1替换value2的值
注:扩容时,当超出临界值(且要存放的位置不是null)。 扩容为原来的2倍
- jdk8相较于jdk7在底层实现方面的不同
1、new HashMap():底层没有创建一个长度16的数组
2、jdk8底层的数组是:Node[],而非Entry[]
3、首次调用put()方法时,底层创建长度16的数据
4、jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储。
DEFAULT_INITIAL_CAPACITY
HashMap的默认容量:16
DEFAULT_LOAD_FACTOR
HashMap的默认加载因子:0.75
threshold
扩容的临界值 = 容量填充因子:160.75=>12
TREEIFY_THRESHOLD
Bucket中链表长度大于该默认值,转化为红黑树:8
MIN_TREEIFY_CAPACITY
Node被树化时最小的hash表容量:64
LinkedHashMap(HashMap的子类):
- 保证在遍历Map元素时,可以按照添加的顺序实现遍历。原因:在HashMap的基础上,添加了一对指针,指向前一个和后一个元素(双向链表)。
- 对于频繁的遍历操作,此类执行效率高于HashMap
- 底层:在Entry里面加了befor,after引用,相当于构成一个双向链表
TreeMap:
- 保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序,底层使用红黑树
- 向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
- 因为要按照key进行排序:自然排序,定制排序
HashTable:
- 作为古老的实现类,线程安全,效率低,不可以存储null 的key和value
Properties:
- 常用来处理配置文件。key和value都是String类型
import java.io.FileInputStream;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) throws Exception{
//Properties:常用来处理配置文件。key和value都是String类型
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("set.properties");
prop.load(fis);//加载流对应文件
String name = prop.getProperty("name");
String age = prop.getProperty("age");
System.out.println(name);//fhz
System.out.println(age);//20
}
}
网友评论