11.6 Map接口
Map综述及其用法
package atguigu.java;
import org.junit.Test;
import java.util.*;
/**
* 一、Map的实现类的结构
* Map----双列数据,存储key-value对的数据-------类似于高中的函数:y=f(x)
* HashMap:作为Map的主要实现类;线程不安全,效率高;存储null的 key和 value
* LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历
* 原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素
* 对于频繁的遍历操作,此类执行效率要高于HashMap。
* TreeMap:保证按照添加的key-value进行排序,实现排序遍历。此时考虑key的自然排序或定制排序
* 底层使用红黑树
* Hashtable:作为古老实现类,线程安全,效率低;不能存储null的 key和 value
* Properties:常用来处理配置文件。key-value都是String类型
*
* HasMap的底层:数组+链表(jdk7及之前)
* 数组+链表+红黑树(jdk 8)
*
*
* 面试题
* 1.HashMap的底层实现原理?
* 2.HashMap 和 Hashtable的异同
* 3.CurrentHashMap 与 Hashtable异同(暂时不讲)
*二、Map结构的理解
* Map中的key:无序的,不可重复的,使用Set存储所有的key -------->key所在的类要重写equals()和hashCode()(以HashMap为例)
* Map中的value:无序的,可重复的,使用Collection存储所有的value -------->value所在的类要重写equals()
* 一个键值对:key-value构成一个Entry对象
* Map中的entry:无序的、不可重复的,使用Set存储所有的entry
*
* 三、HashMap的底层实现原理?以jdk7为例说明:
* HashMap map = new HashMap():
* 在实例化以后,底层创建了长度是16的一维数组Entry[] table
* ....可能已经执行过多次put.......
* map.put(key1,value1):
* 首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置
* 如果此位置上的数据为空,此时key1-value1添加成功 --------情况1
* 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或
* 多个数据的哈希值:
* 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况2
* 如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals()方法,比较
* 如果equals()返回false,添加成功-----情况3
* 如果equals()返回true,使用value1替换value2。
*
* 补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。
*
* 在不断的添加过程中,会涉及到扩容问题,当超出临界值时(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
*
* jdk 8 相较于jdk 7 在底层实现方面的不同:
* 1.new HashMap():底层没有创建一个长度为16的Entry数组
* 2.jdk 8底层的数组是:Node[],而非Entry[]
* 3.首次调用put()方法时,底层创建长度为16的数组
* 4.jdk7底层结构只有:数组 + 链表,jdk8中底层结构:数组+链表+红黑树
* 当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为
* 使用红黑树存储。
* 四、LinkedHashMap底层实现原理(了解)
*
* 五、Map中定义的方法
* 添加删除修改操作
*
*
* 总结:常用方法:
* 添加:put(Object key,Object value)
* 删除:remove
* 修改:put
* 查询:get
* 长度:size()
* 遍历:keySet()/values()/entrySet()
* @author xq
* @create 2020-12-29-10:46
*/
public class MapTest {
@Test
public void test4(){
Map map = new HashMap();
map.put("AA",123);
map.put("BB",133);
map.put("CC",143);
//遍历所有的key:ketSet()
Set set = map.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
Collection values = map.values();
for(Object obj : values){
System.out.println(obj);
}
//遍历所有的key-value
//方式一:entrySet()
Set entrySet = map.entrySet();
Iterator iterator1 = entrySet.iterator();
while (iterator1.hasNext()){
Object o = iterator1.next();
//entrySet集合中的元素都是entry
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey() + "------>" + entry.getValue());
}
}
@Test
public void test3(){
Map map = new HashMap();
map.put("AA",123);
map.put("BB",133);
map.put("CC",143);
System.out.println(map.get("AA"));
System.out.println(map.containsKey("aa"));
System.out.println(map.containsValue(123));
}
@Test
public void test2(){
Map map = new HashMap();
//添加
map.put("AA",123);
map.put("BB",133);
map.put("CC",143);
//修改
map.put("AA",153);
System.out.println(map);
Map map1 = new HashMap();
map1.put("AA",173);
map1.put("BB",193);
map.putAll(map1);
System.out.println(map);
//remove(Object key)
Object value = map.remove("CC");
System.out.println(map);
map1.clear();
System.out.println(map1);
}
@Test
public void test1() {
Map map = new HashMap();
map.put(null, 123);
}
}
TreeMap
package atguigu.java;
import org.junit.Test;
import sun.reflect.generics.tree.Tree;
import java.util.*;
/**
* @author xq
* @create 2020-12-29-15:32
*/
public class TreeMapTest {
//向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
//因为要按照key进行排序:自然排序、定制排序
@Test
public void test1(){
TreeMap map = new TreeMap();
map.put("AA",1);
map.put("CC",2);
map.put("BB",3);
map.put("dd",4);
System.out.println(map);
Set entrySet = map.entrySet();
Iterator iterator1 = entrySet.iterator();
while (iterator1.hasNext()){
Object o = iterator1.next();
//entrySet集合中的元素都是entry
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey() + "------>" + entry.getValue());
}
}
//定制排序
@Test
public void test2(){
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("输入的类型不匹配");
}
});
}
}
Properties
package atguigu.java;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
/**
*
*
* @author xq
* @create 2020-12-29-15:54
*/
public class PropertiesTest {
//Properties:常用来处理配置文件。key和value都是String类型
public static void main(String[] args) throws Exception {
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);
System.out.println(password);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis != null){
fis.close();
}
}
}
}
11.7 Collections工具类
package atguigu.java;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Collections:操作Collection,Map的工具类
*
* 面试题:Collection 和 Collections的区别?
* reverse:反转
* shuffle:随机排序
* sort(List):自然排序(升序)
* sort(list,Comparator):指定排序
* swap(List,int,int):交换元素
* int frequency(Collection,Object)返回指定集合中指定元素的出现次数
* void copy(List dest,List src)将src中的内容复制到dest中,dest.size()>list.size()
*
* @author xq
* @create 2020-12-29-16:27
*/
public class CollectionsTest {
@Test
public void test2(){
List list = new ArrayList();
list.add(123);
list.add(23);
list.add(-123);
list.add(144);
list.add(76);
List dest = Arrays.asList(new Object[list.size()]);
System.out.println(dest);
//返回的list1是线程安全的
List list1 = Collections.synchronizedList(list);
}
@Test
public void test1(){
List list = new ArrayList();
list.add(123);
list.add(23);
list.add(-123);
list.add(144);
list.add(76);
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
Collections.shuffle(list);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
Collections.swap(list, 1, 3);
System.out.println(list);
}
}