2020-09-17(Set接口和Map接口)

set集合特点:

- 无序(元素顺序与放入顺序无关),不能按索引访问元素
- 不可重复(集合中不允许出现重复的元素)
  实现类:HashSet、TreeSet

1. HashSet(相对无序存储,不可以存储相同元素(排重),通过哈希表实现的集)
   此类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。

Hash:哈希——实际含义散列,就是一种算法,把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。

哈希表:数组加链表,既有数组的优点也有链表的优点。

HashSet的去重原理
    第一步:先判断你说添加的对象和set集中对象的hashCode()有没有相同的,如果没有,则直接添加进            
    去,如果有相同的hashCode()方法的返回值,则进行第二步
    第二步:此时再去将两个相同hashCode方法相同的对象,去执行equals判断,如果返回的是true,那么此    
    时就会判断这两个对象是重复值,那么第二个就不能添加了,如果是false,那就可以添加

因此,向Set集合中添加元素时,需要重写hashCode()和equals()方法,防止相同元素被添加到Set集合中

重写hashCode()
    hashCode()是Object中的方法,每个对象的hashCode值是唯一的,所以可以理解成hashCode值表示这个对象在内存中的位置,字符串String的hashCode(),是根据内容计算的。
重写equals()
    equals()方法是Object类中的方法,表示比较两个对象是否相等,若不重写相当于比较对象的地址,
所以我们可以尝试重写equals方法,检查是否排重。


2.TreeSet
​	TreeSet是用于对元素进行排序的有序集合类,不允许有重复的元素,不保证元素顺序与插入顺序一致
- 数据结构:二叉树
- 特点:元素是有大小顺序的

​TreeSet会对元素进行排序,排序的依据:

元素本身具有的自然顺序,当不可自己排序时:
1.让JavaBean实现`Comparable`接口,实现compareTo()方法,让对象自身具有可比较性
2.提供一个比较器,根据比较器进行排序
  定义一个比较器,实现`Comparator`接口的类,实现compare()方法
  在创建TreeSet时传入比较器
3.匿名内部类,重写compare()方法

TreeSet判断重复的依据:当添加的两个元素的compareTo()返回值为0时,则认为是相同元素
Map集合特点

Map是专门用来处理 键值映射数据 的一种集合,可以根据key键实现对value值的操作

- 是一种映射关系,称为键值对(key-value)
- key必须是唯一,不允许重复
- 一个key只能对应一个value,但一个value可以有多个key与之对应
- 不保证元素的顺序与插入的顺序一致,不能按索引访问元素

​   实现类:HashMap、Hashtable、Properties

1. HashMap

基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序。

存储特点:
	相对无序存储,元素以键值对形式存在,键不可以重复,值可以重复,元素整体排重,可以快速的通过键查找到所对应的值,通过哈希表实现的集合。
	从底层中了解到,HashSet就是HashMap的键,所以HashSet的去重规则也适用我们HashMap的键去重(重写hashCode()和equals方法)
	

Map集合的排重,只需要重写键所属的类的hashCode和equals方法即可。

map集合中若向集合中添加相同键的键值对时,新的值会将旧的值覆盖。
上述代码中map集合中有两个键值对,分别为:张三-12---二哈,lisi-12---旺财

​ 遍历HashMap的三种方式:

- 通过keySet()获取所有key的集合,然后遍历所有的key
- 通过values()获取所有value的集合,然后遍历所有的value
- 通过entrySet()获取所有的key-value的集合,然后遍历所有的key-value键值对




HashMap<Integer, Student> map = new HashMap<Integer, Student>();

Student stu1 = new Student(1001, "tom");
Student stu2 = new Student(1002, "jack");
Student stu3 = new Student(1003, "mike");

// 将学号作为key,将学生对象作为value
map.put(stu1.getNo(), stu1);
map.put(stu2.getNo(), stu2);
map.put(stu3.getNo(), stu3);

// Map本身无法遍历

/*
 * 方式1:遍历所有的key
 */
Set<Integer> keys = map.keySet(); // 返回所有kery的集合
for (Integer key : keys) {
	Student value = map.get(key);
	System.out.println("key:" + key + ",value:" + value);
}
System.out.println("--------------------------------");

/*
 * 方式2:遍历所有的value
 */
Collection<Student> values = map.values();
for (Student value : values) {
	System.out.println(value);
}
System.out.println("--------------------------------");

/*
 * 方式3:遍历所有的key-value
 * Map.Entry就表示key-value
 * 	返回一个Set集合,Set集合的泛型是Map.Entry类型
 * 	Map.Entry的泛型是Map集合的泛型
 */
Set<Map.Entry<Integer, Student>> entries = map.entrySet();
Iterator<Entry<Integer, Student>> it = entries.iterator();
while(it.hasNext()){
	Entry<Integer, Student> entry = it.next(); //获取Entry(key、value)
	Integer key = entry.getKey();
	Student value = entry.getValue();
	System.out.println("key:"+key+",value:"+value);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值