Set集合:
HashSet集合(元素唯一):
无序(存储和取出不一致),能够保证元素唯一
HashSet:底层数据结构是一个哈希表(桶结构)
线程不安全的类→→→不同步→→→执行效率高
JDK8以后;提供了juc(并发包:java.util.concurrent):
ConcurrentHashMap<K,V>和HashMap的区别 ?
String类型:String类型本身已经重写了hashCode()和equals,如果hashCode和equals()都相同,
那么认为同一个元素,存储以前的值
public class HashSetDemo {
public static void main(String[] args) {
//创建HashSet集合对象
Set<String> set = new HashSet<>() ;
//添加字符串元素
set.add("hello") ;
set.add("hello") ;
set.add("world") ;
set.add("JavaEE") ;
set.add("JavaEE") ;
set.add("world") ;
set.add("android") ;
set.add("php") ;
set.add("php") ;
set.add(null) ;
System.out.println(set); //元素唯一,会自动去重
}
}
如果现在存储是自定义对象,如何保证元素唯? ---- HashSet
HashSet集合依赖于add方法→→→HashMap的put方法
首先要比较元素的哈希码值相同→→→hash()就相同,还要比较成员信息是否相同,对应存储自定的类必须要重写Object的equals方法
比如Student的这个类,必须手动给出hashCode()和equals
(无序)Hashset集合不能保证顺序迭代恒久不变!
注意:
在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一!
类型:String,Integer,Long,....常用类都已经重写了hashCode和equals方法
手动给出HashCode() 和 equals方法
idea快捷键直接生成 alt+insert
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
TreeSet集合(自然排序):
无序性,元素唯一
底层依赖于TreeMap集合, 红黑树结构(也称为 "自平衡的二叉树结构"),可以实现Map的自然排序以及比较器排序取决于
构造方法:
public TreeSet():构造一个空的树,实现元素自然排序 (取决于存储的元素类型能否实现Comparable接口)
TreeSet能够实现两种排序:
1.自然排序
若要实现TreeSet的自然排序 ,执行TreeSet无参构造方法,而且前提条件当前存储类型必须实现Comparable接口
public class Student implements Comparable<Student>{
private String name ;//姓名
private int age ;//年龄
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//排序的代码
@Override
public int compareTo(Student s) { //后面需要和学生对象对比
//主要条件:就是按照年龄从小到大排序
//定义一个变量
//年龄int类型
/* int num = this.age - s.age ;
// int num = s.age - this.age ;//从大到小
//次要条件:年龄相同,还要比较姓名的内容是否相同
int num2 = (num==0)?(this.name.compareTo(s.name)):num; //字符串的字典顺序比较
//gaoyuanyuan
//jacky
return num2;*/
//主要条件:按照学生姓名的长度:从小到大进行排序
int num = this.name.length() - s.name.length() ;
//如果长度相同,还比较内容是否一样 "hello" ,"hel"
int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
//如果长度相同,内容一样
//按照学生的年龄从小到大比
int num3 = (num2==0)? (this.age - s.age) :num2 ;
return num3 ;
}
}
需求:
使用TreeSet集合存储学生类型
主要条件:按照学生姓名的长度:从小到大进行排序
public class TreeSetDemo3 {
public static void main(String[] args) {
//无参构造方法创建TreeSet集合
TreeSet<Student> ts = new TreeSet<>() ;
//创建几个学生对象
Student s1 = new Student("wenzhang",34) ;
Student s2 = new Student("zhaosisi",36) ;
Student s3 = new Student("wuyifan",40) ;
Student s4 = new Student("wuyifan",32) ;
Student s5 = new Student("gaoyuanyuan",42) ;
Student s6 = new Student("gaoyuanyuan",42) ;
Student s7 = new Student("zhangjunjie",20) ;
Student s8 = new Student("liuqiangdong",50) ;
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
//遍历
for(Student s: ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
运行结果
wenzhang---34
zhaosisi---36
wuyifan---40
wuyifan---32
gaoyuanyuan---42
zhangjunjie---20
liuqiangdong---50
2.比较器排序:
public TreeSet(Comparator<? super E> comparator)
Comparator是一个接口类型
1)自定义一个类实现Comparator接口,重写compare方法
2)使用接口的匿名内部类(推荐)
使用TreeSet存储Student类型,遍历元素(使用比较器排序完成)
排序条件:
主要条件:按照学生的年龄从小到大排序
泛型高级通配符(了解)
<?> :任意Java类型,包括Object
<? super E> : 向上限定:E类型以及E父类
<? extends E>: 向下限定:E以及它的子类
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
//主要条件:按照学生的年龄从小到大排序
//s1---->就是刚才自然排序里面this
//s2---->就是刚才自然排序里面s
int num = s1.getAge() - s2.getAge() ;
//如果年龄相同,比较姓名是否一样
int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
return num2;
}
}