Map 双列数据,存储key-value对
HashMap:作为Map的主要实现类,线程不安全,效率高,可以存储null值的key和value
LinkedHashMap:可以保证在遍历Map时,按照添加的顺序遍历map。
原因是底层在HashMap存储元素的基础上面,添加了指向前一个和后一个map元素的指针。
对于频繁遍历的map操作可以考虑使用LinkedHashMap。
TreeMap:保证按照添加key-value对进行排序,可以实现排序遍历。此时考虑key的自然排序还是定时排序
底层是红黑树的数据结构。
Hashtable:作为map古老的实现类,线程安全,效率低;不能存储null值的key和value
Properties:常用来处理配置文件,key和value都是string类型的
HashMap的底层数据结构在jdk7和jdk8里面的区别?
jdk7:数组+链表
jdk8:数组+链表/红黑树
常见面试题:
(1)HashMap的底层实现原理?
(2)HashMap和Hashtable的区别?
(3)Hashtable和CurrentHashMap的区别?
package com.sf.MavenLearning0930; import org.junit.Test; import java.util.*; /* 二、Map结构的理解 (1)Map中的Key:无序的,不可重复的,使用Set存储所有的key -----》key所在的类要重写equals()和hashcode()方法(以hashMap为例) (2)Map中的Value:无序的,可以重复的。使用Coolection存储所有的value------》value所在的类要重写equals()方法 (3)Map中的Entry:无序的,不可重复的,使用Set存储所有的Entry 三、HashMap的底层实现 以jdk7为例:HashMap hashMap = new HashMap(); 在实例化以后,底层创建的是一个长度为16的一个数组Entry[] table hashMap.put(key1,value1); put()操作:首先调用key1所在类的hashcode()方法,计算出key1的hash值,再根据某个算法计算出再Entry[]数组里面的位置。 如果此位置上面的数据为空,此时(key1,value1)添加成功-----情况1 如果此位置上面的数据不为空(此位置上面可能存在一个或多个数据(以链表的形式存在),比较key1和已经存在数据key的hash值) 如果hash值都不相同,此时(key1,value1)添加成功-------情况2 如果hash值和某个数据(key2,value2)的hash值相同,继续比较调用key1.equals(key2)进行判断 如果返回false,此时(key1,value1)添加成功-------情况3 如果返回true,使用value1替换value2 补充:对于情况2和情况3,此时(key1,value1)与原有的数据以链表的形式存储 在不断添加元素的过程中,会涉及到hashmap的扩容问题。当长度超过临界值且当前存放数据的位置不为空的时候就需要扩容。 默认的扩容方式是扩到原来长度的2倍并将原有的数据复制过来,这个复制的时候原来元素在数组中的位置可能会发生很大改变。 临界值 = 数组长度 * 阈值; jdk8相较于jdk7的不同? (1)在HashMap hashMap = new HashMap();的时候没有;立即创建一个长度为16的数组,而是在首次put()的时候创建的。 (2)jdk8底层的数组是Node[]而不是Entry[] (3)jdk7 HashMap的底层只有数组加链表的结构,jdk8的HashMap的底层是数组+链表/红黑树 (4)当数组某一个索引位置上的元素以链表的形式存在的数据个数>8且当前数组的长度>64,此时此索引位置上面的所有数据改为使用红黑树存储。 Map里面的常用操作: 增:map.put("ww","12"); 删:map.remove("qq"); 改:map.put("ww","12"); 查:map.get("ee"); 长度:map.size(); 遍历: */ public class MapTest { @Test public void test(){ HashSet hashSet = new HashSet(); HashMap hashMap = new HashMap(); hashMap.put(1,1); hashMap.put(2,null); hashMap.put(null,null); hashMap.put(null,1); System.out.println(hashMap); } @Test public void test02(){ HashMap<String,String> map = new HashMap(); map.put("ww","12"); map.put("qq","14"); map.put("ee","13"); System.out.println(map.get("ee")); // map.remove("qq"); System.out.println(map); // System.out.println(map.size()); System.out.println("-------------------"); //遍历key Set<String> key = map.keySet(); Iterator<String> iterable = key.iterator(); while (iterable.hasNext()){ System.out.println(iterable.next()); } System.out.println("------------------"); //遍历value Collection collection = map.values(); Iterator iterator1 = collection.iterator(); while (iterator1.hasNext()){ System.out.println(iterator1.next()); } System.out.println("------------------"); //遍历key-value 方法1 Set entries = map.entrySet(); Iterator iterator3 = entries.iterator(); while (iterator3.hasNext()){ Map.Entry<String,String> a = (Map.Entry<String,String>)iterator3.next(); System.out.println(a.getKey() + "----" + a.getValue()); } //遍历key-value 方法2 Set<String> key1 = map.keySet(); Iterator<String> iterable4 = key1.iterator(); while (iterable4.hasNext()){ String keys = iterable4.next(); String values = map.get(keys); System.out.println(keys + "=" + values); } } }
Properties举例子:
jdbc.Properties里面的内容 name=jin password=123456
package com.sf.MavenLearning0930;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) {
FileInputStream fis = null;
try{
Properties pros = new Properties();
fis = new FileInputStream("jdbc.Properties");
pros.load(fis);
String name = pros.getProperty("name");
String password = pros.getProperty("password");
System.out.println(name + "-------" + password);
}catch (IOException e){
e.printStackTrace();
}finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Collections工具类:操作Collection、Map的工具类