集合-Map
Map下的接口及其多个实现类
1.Map :双列数据存储key-value对的数据,---类似于高中弄的函数:y=f(x)
(1)HashMap:作为map的主要实现类,线程不安全的,效率高,存储在null的key-value
①存储在null的key和value如下图所示
LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历,是因为在原有的hashmap底层结构的基础上,添加了一对指针直向前一个和后一个元素
(2)TreeMmap:保证按照添加的key-value 对进行排序,实现排序遍历,此时考虑key的自然排序,或者定制排序,底层使用红黑树
(3)Hashtable :作为古老的实现了线程安全的,效率低,不能存储null的key-value
①不能存储null的dekey和value如下图所示
2.map中存储key - value的特点
(1)Map中的key是无序的,不可重复的,使用set存储所有的key -->key所在的类要重写equals和hashcode方法(以hashmap为例)
(2)Map中的value:无序的,可重复的,使用collection存储所有的value,--->value所在的类要重写equals()
一个键值对:key-value构成一个entry对象
Map中的entry:无序的,不可重复的,使用set存储有的entry;
3.hashmap的底层实现原理:
以jdk7为例说明:
(1)HashMap map = new HashMap():在实例化以后,底层创建了一个长度为16的一维数组.
map.put(key1,value1)😕/首先,调用key1所在类的hashCode()计算key1的哈希值,次哈希值经过某种算法计算以后,得到在entry数组中的存放位置。
①如果此位置上的数据为空,此时的key1-value1添加成功。
②如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在),比较key1和已经存在的一个或多个数据的哈希值:
如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功
如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较,调用key1所在类的equals(key2)方法,比较:
如果equals()返回false:此时key1-value1添加成功
如果equals()返回true:使用value1替换value2
jdk8相较于jdk7在底层实现方面的不同:
(1)new HashMap():底层没有创建一个长度为16的数组
(2)jdk 8 底层的数组是:Node[],而非entry[]
(3)首次调用put()方法时,底层创建了长度为16的数组
(4)jdk7底层结构只有:数组+链表,jdk8中底层结构,数组+链表+红黑树
当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,此时此索引位置上的所有数据改为使用红黑树存储,可以使得查找效率增加。
4.Map接口:常用方法
(1)添加、删除、修改方法
点击查看代码
@Test
public void test(){
Map map = new HashMap();
// map = new Hashtable();
//Object put(Object key, Object value):将指定key-value添加到(或修改)当前map对象中
map.put("Twq",23);
map.put("AA",46);//这里添加AA及其对应的value值
map.put("CC",34);
map.put("BB",12);
map.put(45,12);
map.put("AA",12);//当AA关键值已经存在的时候,就修改其对应的value值
System.out.println(map);
System.out.println("==================");
//void putAll(Map m):将m中所有key-value对存放到当前map中
Map map1 = new HashMap();
map1.put("CC",12);
map1.put("DD",1212);
map.putAll(map1);//若map1中存在与map中key值相同的值,则将会修改原来map中的key的值
System.out.println(map);
System.out.println("==================");
//Object remove(Object key)移除指定key的key--value对,并返回value,若key值不存在,则返回null
Object value = map.remove("CC");
System.out.println(value);
System.out.println(map);
System.out.println("==================");
//void clear()清空当前map中的所有数据
map.clear();//与map = null操作不同,map集合还在,只是里面没有数据
System.out.println(map.size());
System.out.println(map);
}
(2)元素查询操作
点击查看代码
@Test
public void test1(){
Map map = new HashMap();
map.put("Twq",23);
map.put("AA",46);
map.put(12,34);
//Object get(Object key):获取指定key对应的value,若没有的话就就会返回null
System.out.println(map.get(12));
System.out.println("================");
//boolean containskey(object key):是否包含指定的key
System.out.println(map.containsKey("Twq"));
System.out.println(map.containsValue(42));
System.out.println("================");
//boolean equals(Object obj):判断当前map和参数对象obj是否相同
Map map1 = new HashMap();
map1.put("Twq",23);
map1.put("AA",46);
map1.put(12,34);
System.out.println(map.equals(map1));
}
(3)元视图的操作方法
点击查看代码
@Test
public void test2(){
//Set keySet():返回所有key构成的Set集合
//遍历所有的key集:keyset()
Map map = new HashMap();
map.put("Twq",23);
map.put("AA",46);
map.put(12,34);
Set set = map.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("===============");
//遍历所有的value:values()
Collection coll= map.values();
for(Object obj : coll){
System.out.println(obj);
}
System.out.println("=================");
//遍历所有的key-value:
Set set1 = map.entrySet();
//方式一:entrySet()
Iterator iterator1 = set1.iterator();
while(iterator1.hasNext()){
Object obj = iterator1.next();
//entrySet集合中的元素都是entry
Map.Entry entry = (Map.Entry)obj;
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
System.out.println();
//方式二:
Set set2 = map.keySet();
Iterator iterator2 = set2.iterator();
while(iterator2.hasNext()){
Object key = iterator2.next();
Object value = map.get(key);
System.out.println(key + "===" + value);
}
}
5.TreeMap
(1)向TreeMap中添加key -- value ,要求key必须是由一个类创建的对象
(2)因为要按照key进行排序:自然排序,定制排序
①自然排序:
点击查看代码
@Test
public void test3(){
Person p1 = new Person("Tom", 23);
Person p2 = new Person("Jerry", 32);
Person p3 = new Person("Mike", 20);
Person p4 = new Person("Rose", 18);
TreeMap map = new TreeMap();
map.put(p1,98);
map.put(p2,113);
map.put(p3,28);
map.put(p4,43);
Set set = map.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
Map.Entry entry = (Map.Entry)obj;
System.out.println(entry.getKey() + "--->"+entry.getValue());
}
}
②定制排序
点击查看代码
@Test
public void test4(){
Person p1 = new Person("Tom", 23);
Person p2 = new Person("Jerry", 32);
Person p3 = new Person("Mike", 20);
Person p4 = new Person("Rose", 18);
TreeMap map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Person && o2 instanceof Person){
Person p1 = (Person) o1;
Person p2 = (Person) o2;
return Integer.compare(p1.getAge(),p2.getAge());
}
throw new RuntimeException();
}
});
map.put(p1,98);
map.put(p2,113);
map.put(p3,28);
map.put(p4,43);
Set set = map.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
Map.Entry entry = (Map.Entry)obj;
System.out.println(entry.getKey() + "--->"+entry.getValue());
}
}
5.Map实现类Properties
主要用来处理属性文件,key和value都是String类型
(1)新建properties方法:注意要在项目名下新建,不能在包名下新建
(2)使用方法
点击查看代码
@Test
public void test5() throws Exception {
Properties pro = new Properties();
FileInputStream fis = new FileInputStream("jdbc.properties");
pro.load(fis);//加载流对应的文件
String name = pro.getProperty("name");
String password = pro.getProperty("password");
System.out.println("name = " + name+",password = " + password);
}
(3)注意事项