Map体系集合
Map接口的特点:
- 用于存储任意键值对(Key-Value)
- 键(key):无序,无下标,不允许重复(唯一)
- 值(value):无序,无下标,允许重复
Map父接口
特点:存储一对数据(Key-Value),无序,无下标,键不可重复,值可重复。
方法:V put(K key,V value)// 将对象存入到集合中,关键的值。key重复则覆盖原值
Object get(Object key) //根据键获取相对的值。
KeySet (key,map.get(key)) //返回所有的key。
Collectionvalues() //返回包含所有值Collection集合。
Set<Map.Entry<K,V>> //键值匹配的Set集合。
Map接口使用
package Map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
//创建map集合
Map<String,String> map = new HashMap<>();
//1.添加元素
map.put("cn","中国");//key,value
map.put("uk","英国");
map.put("usa","美国");
System.out.println("元素个数:"+map.size());
System.out.println(map.toString());
//2.删除
// map.remove("usa");
// System.out.println(map.toString());
//3.遍历
//3.1使用KeySet();
// Set<String> keyset = map.keySet();
// for(String key : keyset){
//另一种写法
for (String key : map.keySet()){
System.out.println(key+"---"+map.get(key));
}
//3.2使用entrySet()方法
//entry包含一个 key 和 value
System.out.println("===================");
Set<Map.Entry<String,String>> entries = map.entrySet();
for (Map.Entry<String,String> entry : entries){
System.out.println(entry.getKey()+"------"+entry.getValue());
}
//4.判断
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("中国"));
}
}
HashMap使用
初始容量(16)和默认加载因子(0.75)的空HashMap扩容。
使用key可hashcode和equals作为重复,可重写方法来判断重复
package Map;
import java.util.HashMap;
import java.util.Map;
/**
* HashMap集合的使用
* 存储结构:哈希表(数组+链表+红黑树)
*/
public class Demo02 {
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);
students.put(s1,"北京");
students.put(s2,"上海");
students.put(s3,"杭州");
// students.put(s3,"南京");//值可以重复,key不可以,所以加不进去
students.put(new Student("沙和尚",102),"南京");//在堆里面new一个对象,新的地址
System.out.println("元素个数:"+students.size());
System.out.println(students.toString());
//2.删除
// students.remove(s1);
// System.out.println("删除之后:"+students.size());
System.out.println("========================");
//3.遍历
//3.1使用keySet();
for (Student key : students.keySet()){
System.out.println(key.toString()+"===="+students.get(key));
}
System.out.println("========================");
//3.2使用entrySet();
for(Map.Entry<Student,String> entry : students.entrySet()){
System.out.println(entry.getKey()+"------"+entry.getValue());
}
//4.判断
System.out.println(students.containsKey(new Student("孙悟空",100)));
System.out.println(students.containsValue("北京"));
}
}
HashMap源码分析
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
初始容量 2^4 = 16
static final int MAXIMUM_CAPACITY = 1 << 30;
最大容量 2^30
static final float DEFAULT_LOAD_FACTOR = 0.75f
加载因子,容量超过百分之75%之后扩容,扩容至原来的两倍
static final int TREEIFY_THRESHOLD = 8;
当数组大于64,链表大于8,就形成树
static final int UNTREEIFY_THRESHOLD = 6;
链表小于6就形成链表
static final int MIN_TREEIFY_CAPACITY = 64;
最小数组容量
刚创建HashMap对象时
table = null
size = 0
添加第一个元素后容量才变化,利于节省空间。
resize,扩容
Hashtable和Properties
Hashtable:
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
Properties:【常用】
Hashtable的子类,需求key和value都是String。通常用于配置文件的读取
TreeMap
ClassCastException:类型转换异常
红黑树结构需要比较数两边大小,而Student类没有比较
需要实现比较类
public class Student implements Comparable
@Override
public int compareTo(Student o) {
int n2 = this.stuNO - o.getStuNO();
return n2;
}
也可以定制比较
Collections工具类
概念:集合工具类,定义了除了存储意外的集合常用方法。
方法:
public static void reverse(List<?> list) // 反转集合中的元素的顺序
public static void shuffle(List<?> list) //随机重置集合元素的顺序
public static void sort(List list) // 升序排序(元素类型必须实现Comparable接口
package Map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Demo04 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(5);
list.add(12);
list.add(30);
list.add(6);
//sort排序
System.out.println("排序之前:"+list.toString());
Collections.sort(list);
System.out.println("排序之后:"+list.toString());
//binarySearch二分查找法
int i = Collections.binarySearch(list,13);
System.out.println(i);
//copy赋值
List<Integer> dest = new ArrayList<>();
for (int i1 = 0; i1< list.size();i1++){
dest.add(0);
}
Collections.copy(dest,list);
System.out.println(dest.toString());
//revers反转
Collections.reverse(list);
System.out.println("反转之后:"+list);
//shuffle 打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);
//补充:list转成数组
Integer[] arr = list.toArray(new Integer[0]);//小于list则输出本来的长度,大于则其余的为null
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
//数组转成集合
String[] names = {"张三","李四","王五"};
//集合是一个受限集合,不能添加和删除
List<String> list2 = Arrays.asList(names);
System.out.println(list2);
//把基本类型转换成集合时,需要修改为包装类
Integer[] nums = {100,200,300,400,500};
List<Integer> list3 = Arrays.asList(nums);
System.out.println(list3);
}
}
IndexOutOfBoundsException
复制时,数组长度需要一致
做一个循环