2.5.3 Set:接口
2.5.3.1 HashSet
特点:无序,唯一
数据结构:基于哈希表
HashSet1:基本用法及特点 创建一个HashSet集合对象: HashSet<泛型> set = new HashSet<>();
如何添加元素: set.add(元素);
Collections.addAll(set,元素,元素…);
得到集合的大小set.size()
判断集合里面是否存在某个元素set.contains(元素)
由于HashSet是无序的 所以没有:get(下标)/remove(下标)/for + 下标方法
求两个集合的并集:集合A.addAll(集合B) 求两个集合的差集:集合A.removeAll(集合B) 求两个集合的交集:集合A.retainAll(集合B)
HashSet2:HashSet唯一性 唯一: 内存里面的同一个对象不能往HashSet集合添加多次
“唯一”: 内存里面的两个对象 但是视为相等对象,从而只能往HashSet集合里面添加一次
HashSet3:验证hashSet的唯一性
取决于hashCode和equals两个方法
hashCode():当一个对象要被添加进HashSet集合的时候 底层会自动的通过对象得到哈希码值
equals():判断两个对象能不能视为相等对象,当一个对象去到某个小组之后 发现这个小组里面 有一个对象的哈希码值和新来元素的哈希码值一样,需要拿着equals()挨个做比较
hashSet4:HashSet添加元素的时候, 有一套完整流程 :
先比较hashCode() ,然后比较地址== ,最后比较equals()
? 如果两个对象哈希码值一样: ? a:这两个对象是内存里面的同一个对象 x.hashCode() = x.hashCode() ? b:两个对象 但是视为相等对象 x.hashCode() = y.hashCode() ? c:两个对象 没有视为相等对象 重码
hashSet5:HashSet集合在遇到重复元素的时候,舍弃的是新来的元素
hashSet6:底层尊重hashCode() == equals()比较机制 add(元素) remove(元素) contains(元素)
hashSet7:当我们使用迭代器遍历集合的过程中 不允许对集合的整体进行添加、删除操作 否则触发CME异常
? 如果遍历的时候 想要删除的话:ite.remove()
hashSet8:当一个对象已经添加进HashSet集合之后 不要随意的修改那些参与生成哈希码值的属性值,如果在添加之后想要修改的话: 删除 + 修改 + 添加
? 如果一个对象添加进HashSet集合之后 想要修改普通属性[没有参与生成哈希码值] -》 可直接修改
hshSet9:构造方法 HashSet set = new HashSet(int 分组组数,float 加载因子); 第一个参数:分组组数 程序员可以随意的指定 但是最终一定会变成2的n次方数
? 第二个参数:加载因子 ? 控制阈值 ? 阈值:哈希表每个小组最多装多少个元素 ? 阈值:分组组数 * 加载因子
? HashSet set = new HashSet();//默认分16个小组 加载因子0.75F 阈值:12
例1:添加元素的比较机制
import java.util.*;
public class Exec2{
public static void main(String[] args){
HashSet<Student> set=new HashSet<>();
HashSet<Student> set2=new HashSet<>();
Student stu1=new Student("张三",23);
Student stu2=new Student("王麻子",23);
Student stu3=new Student("刘二狗",28);
PrimeryStudent p1=new PrimeryStudent("小明",10,'男');
PrimeryStudent p2=new PrimeryStudent("小红",11,'女');
set.add(stu1);
set.add(stu3);
set2.add(p1);
set2.add(p2);
System.out.println(set.size());
System.out.println(set2.size());
}}
class Student {
String name;
int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
@Override
public boolean equals(Object obj){
return this.age==((Student)obj).age;
}
@Override
public int hashCode(){
return age;}
}
class PrimeryStudent extends Student{
char gender;
public PrimeryStudent(String name,int age,char gender){
super(name,age);
this.gender=gender;
}
@Override
public boolean equals(Object obj){
return this.name.equals(((PrimeryStudent)obj).name)&&this.age==((PrimeryStudent)obj).age&&this.gender==((PrimeryStudent)obj).gender;}
@Override
public int hashCode(){
return age+(gender=='男'?1:0);}
}
例2:HashSet修改元素(删除+修改+添加)
import java.util.*;
public class Exec3{
public static void main(String[] args){
HashSet<User> mry=new HashSet<>();
User u1=new User("张丽","普通用户",1200);
User u2=new User("汪美丽","普通用户",2900);
User u3=new User("赵小雪","普通用户",300);
User u4=new User("张欣","普通用户",590);
User u5=new User("罗浩","普通用户",1900);
User u6=new User("罗浩","普通用户",1900);
Collections.addAll(mry,u1,u2,u3,u4,u5,u6);
LinkedList<User> list=new LinkedList<>();
int count=0;
for(Iterator<User> ite=mry.iterator();ite.hasNext();){
User u=ite.next();
if(u.getJifen()>1200){
ite.remove();
u.setDengji("超级vip");
list.add(u);
count++;
}
}
mry.addAll(list);
System.out.println(mry);
System.out.println("普通用户:"+(100-(count*100/mry.size()))+"%"+"\t超级VIP:"+count*100/mry.size()+"%");
}
}
class User{
private String name;
private String dengji;
private int jifen;
public User(String name,String dengji,int jifen){
this.name=name;
this.dengji=dengji;
this.jifen=jifen;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setDengji(String dengji){
this.dengji=dengji;
}
public String getDengji(){
return dengji;
}
public void setJifen(int jifen){
this.jifen=jifen;
}
public int getJifen(){
return jifen;
}
@Override
public String toString(){
return getName()+":"+getDengji();
}
@Override
public boolean equals(Object obj){
if(obj==null||!(obj instanceof User))return false;
if(obj==this)return true;
return this.getName().equals(((User)obj).getName())&&this.getDengji().equals(((User)obj).getDengji())&&this.getJifen()==((User)obj).getJifen();
}
@Override
public int hashCode(){
return getName().hashCode()+getDengji().hashCode()+getJifen();}
}
2.5.3.2 SoredSet:接口
(Set的子接口)
TreeSet:二叉树
特点:有序(默认升序),唯一
数据结构:二叉树
基本用法及特点
? 创建一个TreeSet集合对象: ? TreeSet<泛型> set = new TreeSet<>();
如何添加元素: set.add(元素);
Collections.addAll(set,元素,元素…);
得到集合的大小set.size()
判断集合里面是否存在某个元素set.contains(元素)
由于TreeSet是默认升序的的 所以没有:get(下标)/remove(下标)/for + 下标方法
特有的四个方法:
获得集合中第一个元素:set.first();
获得集合中最后一个元素:set.last();
删除集合中第一个元素:set.pollFirst();
删除集合中最后一个元素:set.pollLast();
例1:降序打印集合中的数字
import java.util.*;
public class TestTreeSet{
public static void main(String[] args){
TreeSet<Integer> set=new TreeSet<>();
Collections.addAll(set,45,77,10,93,27);
while(set.size()!=0){
System.out.println(set.pollLast());
}
}
}
|