Map集合
Map接口的特点
-
用于存储任意键值对(key - value)
-
键:无序、无下标、不允许重复(唯一)
-
值:无序、无下标、允许重复
方法:
1. V put(K key, V value) 将对象存到集合中,关联键值
2. Object get(Object key) 根据键获得对应的值
3. Set<K> 返回所有的Key
4. Collection<V> values() 返回包含所有值的Collection集合
5. Set<Map.Entry<K, V>> 键值匹配的Set集合
Map接口的使用
创建Map集合 Map<String, String> map = new HashMap<>();
添加元素 map.put(key,value);
删除元素 map.remove();
遍历
-
使用KeySet()
for (String key: map.keySet()) { System.out.println(key + "-----" + map.get(key) ); }
-
使用entrySet
for(Map.Entry<String, String> entry : map.entries){ sout(entry.getKey() + "---" + entry.getValue(); }
判断 map.containsKey("cn")
、 map.containsValue("泰国")
练习
/**
* Map接口的使用
*特点:1.存储键值对 2.键不能重复,值可以重复 3.无序
*/
public class Demo1 {
public static void main(String[] args) {
//创建Map集合
Map<String, String> map = new HashMap<>();//指定两个类型,<key,value>。由于Map是个接口,所以只能使用实现类HashMap
//1添加元素
map.put("cn","中国");
map.put("uk","英国");
map.put("usa","美国");
map.put("usa","中国的");//同名时,会把前面的替换掉
System.out.println(map.size());
System.out.println(map);
//2删除
map.remove("uk");
System.out.println("删除之后:" + map.size());
System.out.println(map);
//3遍历
//3.1使用keySet();
Set<String> keyset = map.keySet();// 所有Key的set集合
for (String key : keyset) { //keySet只能获取key
System.out.println(key + "-----" + map.get(key) );//map里面有个get方法,可以通过key获取value
}
//上面两句合并成一句
for (String key: map.keySet()) {
System.out.println(key + "-----" + map.get(key) );
}
//3.2使用entrySet();
Set<Map.Entry<String,String>> entries = map.entrySet();
for (Map.Entry<String,String> entry: entries) {
System.out.println(entry.getKey() + "-----" + entry.getValue());//entrySet可以直接获取整个键值对,所以效率更高。
}
//上面两句合并
for (Map.Entry<String,String> entry: map.entrySet()) {
System.out.println(entry.getKey() + "-----" + entry.getValue());
}
//4判断
System.out.println(map.containsKey("cn")); //判断key
System.out.println(map.containsValue("泰国")); //判断value
}
}
HashMap【重点】
- 存储结构:哈希表(数组+链表+红黑树)
- 使用key可使hashcode和equals作为重复
- 增、删、遍历、判断与上述一致
/**
* HashMap集合的使用
* 存储结构:哈希表(数组 + 链表 + 红黑树)
* 使用key的hashCode和equals作为重复
* */
public class Demo2 {
public static void main(String[] args) {
//创建集合
HashMap<Student,String> students = new HashMap<Student,String>();
//添加元素
Student s1 = new Student("孙悟空",100);
Student s2 = new Student("猪八戒",101);
Student s3 = new Student("沙和尚",102);
Student s4 = new Student("唐玄藏",103);
students.put(s1,"北京");
students.put(s2,"上海");
students.put(s3,"杭州");
students.put(s4,"西安");
students.put(s3,"南京");//不允许重复
students.put(new Student("沙和尚",100),"西安");
System.out.println("元素的个数是:" + students.size());
System.out.println(students.toString());
//2删除
students.remove(s1);
System.out.println("元素的个数是:" + students.size());
//遍历
//3.1使用keySet();
for (Student key: students.keySet()) {
System.out.println(key.toString()+"-----"+ students.get(key));
}
//3.2使用entrySet
for (Map.Entry<Student, String> entry: students.entrySet()){
System.out.println(entry.getKey() + "-----" + entry.getValue());
}
//判断
System.out.println(students.containsKey(s1));
System.out.println(students.containsKey(new Student("唐玄藏",103)));
System.out.println(students.containsValue("西安"));
}
}
原码分析总结:
- HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
- jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
- jdk1.8 当链表长度 <6 时 调整成链表
- jdk1.8 以前,链表时头插入,之后为尾插入
HashSet和HashMap的关系:
- HashSet的原码内部用的就是HashMap
Hashtable
- 线程安全,运行效率慢;不允许null作为key或是value
Properties
- hashtable的子类,要求key和value都是String,通常用于配置文件的读取
TreeMap
-
实现SorteMap接口(是map的子接口),可以对key自动排序
/** * TreeMap的使用 * 存储结构:红黑树 * */ public class Demo3 { public static void main(String[] args) { //新建集合 TreeMap<Student,String> treeMap = new TreeMap<Student,String>(); //新建集合方法2(定制比较) TreeMap<Student,String> treeMap1 = new TreeMap<Student, String>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { //内部写比较规则 return 0; } }); //1添加元素 Student s1 = new Student("孙悟空",100); Student s2 = new Student("猪八戒",101); Student s3 = new Student("沙和尚",102); Student s4 = new Student("唐玄藏",103); treeMap.put(s1,"北京"); treeMap.put(s2,"上海"); treeMap.put(s3,"西安"); treeMap.put(s4,"湖南"); treeMap.put(new Student("蜘蛛精",100),"南京");//重写的compareTo是根据年龄进行比较,年龄一样就添加不进去,但是地点会被替换为”南京“ System.out.println(treeMap.size()); System.out.println(treeMap.toString()); //2删除 treeMap.remove(s2); System.out.println(treeMap.size()); treeMap.remove(new Student("唐三彩",103));//只要年龄一样就会被删除 System.out.println(treeMap.size()); //遍历 //3.1使用keySet for (Student key: treeMap.keySet()) { System.out.println(key+"------"+ treeMap.get(key)); } //3.2使用Entry for (Map.Entry<Student, String> entry: treeMap.entrySet()) { System.out.println(entry.getKey()+"-----"+entry.getValue()); } //判断 System.out.println(treeMap.containsKey(new Student("沙和尚",100)));//根据Key判断 } }