1. Map接口
Map接口的特点
-
map集合的结构是:键值对、KEY与VALUE、Map.Entry<K,V>的映射关系
-
map中key值不允许重复,如果重复,对应的value会被覆盖
-
map中的映射关系是无序的
-
map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代
Map集合方法总结
简单方法:
map单个集合间的操作
map的迭代
package cn.tedu.map;
import java.util.*;
/*本类用于测试map接口*/
public class MapDemo {
public static void main(String[] args) {
//1.创建map对象
/*Map中的数据要符合映射规则,需要同时制定k与v的数据类型
* 至于k和v具体制定成什么类型,取决于业务的具体要求*/
Map<Integer, String> map = new HashMap();
//2.向Map集合存入数据,取决于业务的具体要求
map.put(9527, "白骨精");
map.put(9528, "黑熊精");
map.put(9529, "鲤鱼精");
map.put(9530, "黄毛怪");
map.put(9531, "黑熊精");
map.put(9527, "女儿国国王");
System.out.println(map);//{9527=白骨精, 9528=黑熊精, 9529=鲤鱼精, 9530=黄毛怪}
/*1.map中存放着的都是无序的数据
* 2.map中的value中的value可以重复
* 3.map中的key不允许重复,如果重复,新value会把旧value覆盖
* 比如女儿国国王和白骨精的key都是9527,白骨精被覆盖掉*/
//3.进行方法测试
// map.clear();//清空集合
// System.out.println(map);//{}
System.out.println(map.equals("黄毛怪"));//false,判断"黄毛怪"是否与集合对象相等
System.out.println(map.isEmpty());//判断是否为空false
System.out.println(map.size());//5,获取map集合中键值对的个数
System.out.println(map.containsKey(9527));//true,判断map集合是否包含指定的key-键
System.out.println(map.containsValue("白骨精"));//false,判断map集合是否包含value-值
//将map集合中的所有value值取出,放入Collection集合中,
//Collection<Type>中Type的类型,取决于map中value的类型
Collection<String> values = map.values();
System.out.println(values);//[女儿国国王, 黑熊精, 鲤鱼精, 黄毛怪, 黑熊精]
//4.map集合的迭代方式1
/*我们降妖谱遍历map中的数据,但是map集合本身没有自己的迭代器,
* 所以需要先将map集合转为Set集合以后,再使用set的迭代器进行迭代
* 代码:Set<Key>=Map.keySet();
* 作用:将map中所有的key值取出,存入set集合中,此处set的泛型是Integer
*/
Set<Integer> set = map.keySet();//将map集合转为set集合,set中存的是map的key
System.out.println(set);//[9527, 9528, 9529, 9530, 9531]
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
// System.out.print(it.next()+" ");//9527 9528 9529 9530 9531
Integer key = it.next();
String value = map.get(key);
System.out.print("("+key+"="+value+")");//(9527=女儿国国王)(9528=黑熊精)(9529=鲤鱼精)(9530=黄毛怪)(9531=黑熊精)
}
//5.map的迭代方式二
/*遍历map集合,需要先把map集合转换为set集合
* 本方案是一对键值对看成是一个Entry
* 代码:Map.Entry<key,value>=map.entrySet();
* Map.Entry<k,v>,这里是Map.Entry<Integer,String>*/
System.out.println("entrySet(--------------------)");
System.out.println();
Set<Map.Entry<Integer, String>> set2 = map.entrySet();
Iterator<Map.Entry<Integer, String>> iterator = set2.iterator();
while (iterator.hasNext()){
Map.Entry<Integer, String> entry = iterator.next();
Integer key = entry.getKey();
String value = entry.getValue();
System.out.print("*"+key+"-"+value+"*");//*9527-女儿国国王**9528-黑熊精**9529-鲤鱼精**9530-黄毛怪**9531-黑熊精*
}
}
}
2.HashMap的存储过程:
-
HashMap的结构是数组+链表 或者 数组+红黑树 的形式
-
HashMap底层的Entry[ ]数组,初始容量为16,加载因子是0.75f,扩容按约为2倍扩容
-
当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量
-
当计算到的位置之前没有存过数据的时候,会直接存放数据
-
当计算的位置,有数据时,会发生hash冲突/hash碰撞 解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素 也就是说数组中的元素都是最早加入的节点
-
如果链表的长度>8并且数组长度>64时,链表会转为红黑树,当链表的长度<6时,会重新恢复成链表
package cn.tedu.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*练习*/
public class Demo {
public static void main(String[] args) {
//1.创建map对象
/*Map中的数据要符合映射规则,需要同时制定k与v的数据类型
* 至于k和v具体制定成什么类型,取决于业务的具体要求*/
Map<Integer, String> map = new HashMap();
//2.向Map集合存入数据,取决于业务的具体要求
map.put(9527, "白骨精");
map.put(9528, "黑熊精");
map.put(9529, "鲤鱼精");
map.put(9530, "黄毛怪");
map.put(9531, "黑熊精");
map.put(9527, "女儿国国王");
System.out.println(map);//{9527=白骨精, 9528=黑熊精, 9529=鲤鱼精, 9530=黄毛怪}
/*迭代方式一*/
Set<Integer> set = map.keySet();
Iterator<Integer> it = set.iterator();
while (it.hasNext()) {
Integer key = it.next();
String values = map.get(key);
System.out.println("*" + key + "=" + values);
}
/*迭代方式二*/
Set<Map.Entry<Integer, String>> entries = map.entrySet();
Iterator<Map.Entry<Integer, String>> entry = entries.iterator();
while (entry.hasNext()) {
Map.Entry<Integer, String> entrys = entry.next();
System.out.println(entrys.getKey());
System.out.println(entrys.getValue());
}
}
}
3. Set接口
Set接口的特点
set集合没有重复的元素 set集合的元素是无序的 set集合可以存null值,并且null最多有一个 我们自定义对象如果想去重,需要在自定义类中添加重写的equals()与hashCode()
集合学习的方法
学习父级的公共方法,学习子类的创建方式,学习各种集合的特点
关于List大多都是与下标有关的操作 关于Set通常都是去重的操作 关于map通常都是映射关系,也就是键值对 API要常练习,方法互相之间没有任何关系,用哪个,查哪个
package cn.tedu.collection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
/*本类用于测试Set*/
public class TestSet {
public static void main(String[] args) {
//1.创建集合对象
HashSet<String> set = new HashSet<>();
set.add("紫霞仙子");
set.add("至尊宝");
set.add("蜘蛛精");
set.add("紫霞仙子");
System.out.println(set);//[蜘蛛精, 至尊宝, 紫霞仙子]
/*1.Set集合中的元素都是没有顺序
* 2.Set集合中的元素不能重复,重复了也没有任何效果
* Set集合可以存null值,只能存一个*/
set.add(null);
set.add(null);
System.out.println(set);//[蜘蛛精, null, 至尊宝, 紫霞仙子]
System.out.println(set.contains("唐僧"));//false,判断集合是否包含唐僧
System.out.println(set.isEmpty());//false
System.out.println(set.remove(null));//true
System.out.println(set);//[蜘蛛精, 至尊宝, 紫霞仙子]
System.out.println(set.size());//3
System.out.println(Arrays.toString(set.toArray()));//[蜘蛛精, 至尊宝, 紫霞仙子]
HashSet<String> set2 = new HashSet<>();
set2.add("小脑服");
set2.add("小兔纸");
set2.add("小海藤");
set2.add("发福蝶");
System.out.println(set2);//[小兔纸, 发福蝶, 小脑服, 小海藤]
set.addAll(set2);
System.out.println(set);//[蜘蛛精, 小兔纸, 发福蝶, 小脑服, 至尊宝, 小海藤, 紫霞仙子]
System.out.println(set.containsAll(set2));//true
System.out.println(set.removeAll(set2));//true
System.out.println(set.contains(set2));//false
// set.retainAll(set2);
// System.out.println(set);//[],没有公共元素
/*Set迭代*/
Iterator<String> it = set2.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");//小兔纸 发福蝶 小脑服 小海藤
}
}
}
package cn.tedu.pojo;
import java.util.Objects;
public class Student {
private String name;
private Integer age;
private char sex;
public Student(String name, Integer age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return sex == student.sex &&
Objects.equals(name, student.name) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
}
package cn.tedu.collection;
import cn.tedu.pojo.Student;
import java.util.HashSet;
/*本类用于测试自定义类对象的去重*/
public class TestSet2 {
public static void main(String[] args) {
HashSet<Student> set = new HashSet<>();
Student s1 = new Student("秦晓燕",18,'女');
Student s2 = new Student("xxx", 30, '男');
Student s22 = new Student("xxx", 30, '男');
/*如果set中存放的是我们自定义的类型
* 需要给自定义类中添加重写的equals()与hashCode(),才会去重
* 不然会认为s2和s22的地址值不同,是两个不同的对象,不会去重*/
set.add(s1);
set.add(s2);
set.add(s22);
System.out.println(set);
}
}