1.Set集合
set集合唯一,无序(没有下标)
常见的实现类:
HashSet 重要
TreeSet 可排序的
LinkedHashSet: 有次序
2.HashSet
实现原理: 借助HashMap, HashSet的存放的元素作为HashMap的key, HashMap的value 静态Object对象
允许空元素
1.四个构造方法
HashSet() 构造一个新的空集合; 背景HashMap实例具有默认初始容量(16)和负载因子(0.75)。
HashSet(Collection<? extends E> c) 构造一个包含指定集合中的元素的新集合。
HashSet(int initialCapacity) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和默认负载因子(0.75)。
HashSet(int initialCapacity, float loadFactor) 构造一个新的空集合; 背景HashMap实例具有指定的初始容量和指定的负载因子。
(1)负载因子是0.75是最优的,一般不更改,集合到负载因子*容量的位置时就会自己扩容
(2)第二个构造方法可以把集合相互转换。
//去重 利用set
Set set1 = new HashSet(list);
//System.out.println(set1);
List list1 = new ArrayList(set1);
System.out.println(list1);
//相互转换
2.HashSet判断这个是否是已存在(contains)
(1)先判断hashcode码,不一样就不是同一个对象
(2)hashcode一样,判断equals(),true就一样
/*将Student类的方法重写*/
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Student student = (Student) o;
return stuno == student.stuno && Objects.equals(name, student.name);}
@Override
public int hashCode() {
return Objects.hash(name, stuno);
/*Random r = new Random();
return r.nextInt();*/
//hashcode码返回随机数,可存放相同的元素
}
3.遍历Hashset
(1)迭代器遍历
//set集合无法通过普通for循环遍历,没有下标
//通过迭代器遍历集合
//1.得到集合的迭代器
/*Iterator iter = set.iterator();
//2.循环获取元素
while(iter.hasNext()){
//获取元素
Object ele = iter.next();
System.out.println(ele);
}*/
(2)forEach循环
for(Object ele : set){
System.out.println(ele);
}
3.TreeSet
树形结构、 唯一、可排序(维护一个排序)
1.四个构造方法
TreeSet() 构造一个新的,空的树组,根据其元素的自然排序进行排序。 TreeSet(Collection<? extends E> c) 构造一个包含指定集合中的元素的新树集,根据其元素的 自然排序进行排序 。 TreeSet(Comparator<? super E> comparator) 构造一个新的,空的树集,根据指定的比较器进行排序。 TreeSet(SortedSet<E> s) 构造一个包含相同元素的新树,并使用与指定排序集相同的顺序。
2.使用自然排序: 元素所在的类实现Comparable接口, 重写conparateTo()方法,
这种排序方式一旦类写好,排序方式固定, 无法再变更, 不灵活
一定要重写方法,因为要排树的序列!
(1)学生类重写方法
public class Student implements Comparable
//创建一个TreeSet 自然排序: Student类实现Comparable接口TreeSet set2 = new TreeSet();
@Override
public int compareTo(Object o) {
//根据学生的年龄升序 小的在左, 大的在右
// 降序: 大的在左, 小的在右
/*
返回正数,表示 this> obj //添加到原来对象(obj)的右边
返回负数,表示 this < obj // 添加到原来对的左边
*/
Student stu = (Student)o;
if(this.equals(stu)){
return 0;
}
/* if(this.age > stu.age){
return -1;
}else{
return 1;
}*/
if(stu.age == this.age){
return 1;
}
//降序 this(新添加元素) stu(以存在)
//大的在左, 小的在右
//返回正数: 新的在旧的右边
//返回负数: 新的在旧的左边
//stu:20 this:21 -1 this stu
// stu:22 this:21 1 stu this
// return stu.age - this.age; //降序
//升序
return this.age - stu.age;
//return 0;
}
(2)匿名内部类, 范围: 在方法内部有效
TreeSet treeSet = new TreeSet(new Comparator(){
@Override
//o1 新添加的元素, o2 旧的元素
public int compare(Object o1, Object o2) {
Student stu1 =(Student) o1;
Student stu2 =(Student) o2;
// return stu1.getStuno() -stu2.getStuno();
return stu2.getStuno() -stu1.getStuno();
}
});
3.记得重写equal和hashcode方法!
4.LinkedHashSet
唯一, 有次序, 没有下标操作
在HashSet基础上额外添加一个链表: 数组+链表/红黑树(哈希表) + 链表, 底层基于LinkedHashMap
使用:购物网站: 你的浏览
性能: 比HashSet低