所在包:java.util public interface Setextends Collection //Set作为接口不能直接进行实例化,必须找到Set相应的实现类。 特点:不包含重复元素的集合 Set集合中没有带索引的方法,所以不能使用普通for循环遍历
注意:
数组用Arrays类方法
集合用Collections类方法
实现代码案例:
Set哈希值概述特点s = new HashSet (); s.add("hello"); s.add("world"); s.add("java"); for(String c:s){ System.out.print(c); //Set对集合的迭代顺序不做任何保证 } 输出结果: world java hello
哈希值:
- 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
- Object类中有hashCode()可以获取对象的哈希值:public Object hashCode()返回对象的哈希值
对象的哈希值特点:
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下(没有在类中重写hashCode()方法的情况下),不同对象的哈希值是不同的,重写hashCode()方法可以让不同对象的哈希值相同
所在包:java.util public class HashSetextends AbstractSet implements Set ,Cloneable,Serializable
特点:
- 底层数据结构是哈希表
- 对集合的迭代顺序不做任何保证,也就是说不保证存储数据和取出数据的元素顺序一致
- 没有带索引的方法,所以不能用普通for循环遍历
- 由于是Set集合,所以在集合中不包含重复的元素
初始化格式:
HashSeths=new HashSet (); 注意:HashSet继承了Set接口所以可以用add、remove、clear、isEmpty、iterator(获取迭代器)等方法
HashSet是如何保证元素不相同的:
- 存入的元素和已经存入的元素比较哈希值
- 如果哈希值不同,则继续向下执行,把元素添加到集合
- 如果哈希值相同,则调用对象的equals方法进一步比较元素值是否相同
- 如果equals返回false,则会继续向下执行,把元素添加到集合
- 如果equals返回true,则说明元素重复,不会向下执行
图例:
存储学生对象案例:
public static void main(String[] args){
HashSet h = new HashSet();
Student s1=new Student("张三",123,99);
Student s2=new Student("李四",456,98);
Student s3=new Student("王五",789,70);
Student s4=new Student("张三",123,99);
h.add(s1);
h.add(s2);
h.add(s3);
h.add(s4);
for(Students:h){
System.out.println(s.getName()+","+s.getId()+","+s.getScore());
}
}
-------------------------------------------------------------------------------------------------
输出结果: // 如果在学生类中重写了方法equals()和hashCode()则不会出现重复对象类型
张三,123,99
李四,456,98
张三,123,99
王五,789,70
注意:继承Set接口下的HashSet输出结果不能保证输入和输出的顺序相同
linkedHashSet< E >
所在包:java.util public class linkedHashSetextends HashSet implements Set ,Cloneable,Serializable
linkedHashSet特点:
- 底层逻辑由哈希表和链表实现的Set接口,具有可预测的迭代次序(存储顺序和输出顺序相同)
- 由链表保证元素的有序性,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素的唯一性,也就是说表中没有重复的元素
代码示例:
linkedHashSetTreeSetlink = new linkedHashSet (); link.add("world"); link.add("hello"); link.add("java"); for(String s:link){ System.out.print(s); } 输出结果: World Hello java
所在包:java.util public class TreeSetextends AbstractSet implements NavigableSet ,Cloneable,Serializable
TreeSet集合特点:
- 元素有序,这里的排序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方法取决于
| 构造方法名 | 作用 |
|---|---|
| TreeSet() | 根据其元素的自然排序进行排序(例:Integer数字按照从小到大的排序顺序) |
| TreeSet(Comparator comparator) | 根据指定的比较器进行指定的排序 |
代码实例:
Public static void main(String[] args){
TreeSet tree = new TreeSet();
//注意集合体只能存储引用类型,如int的包装类类型Integer。
tree.add(9);
tree.add(8);
tree.add(7);
for(Integeri:tree){
System.out.print(i);
}
}
输出结果:
9
8
7
自然排序Comparable的使用范例
案例要求:存储学生对象并遍历,创建TreeSet集合使用无参构造方法。按照年龄从小到大排序,年龄相同时,按照姓名字母顺序排序
代码实现:
在Student类中必须要实现ComparableComparator的使用范例接口并在类中重写compareTo()方法 public class Student implements Comparable { //定义学生类 并实现Comparable接口(自然排序接口) … … @Override //重写compareTo方法 public int compareTo(Student s){ int nums = this.Id-s.Id; //在add方法中调用S2.compareTo(S1); 所以this.Id是指S2中的Id,而s.Id则是S1中的Id //这是一个主要判断排序条件--按照id大小排序 int temp = nums == 0 ? this.Name.compareTo(s.Name) : nums;//nums==0则说明年龄相同,比较姓名 //若姓名相同则返回nums给temp //这是一个次要判断排序条件--按照姓名顺序排序 return temp; } } public class static void main(String[] args){ TreeSet t = new TreeSet (); Student s1=new Student("zs",4,99); Student s2=new Student("ls",3,98); Student s3=new Student("ww",1,99); Student s4=new Student("lw",2,97); Student s5=new Student("ll",2,99); t.add(s1); t.add(s2); t.add(s3); t.add(s4); t.add(s5); for(Students:t){ System.out.println(s.getName()+","+s.getId()+","+s.getScore()); } } 输出结果: ww,1,99 ll,2,99 lw,2,97 ls,3,98 zs,4,99 ------------------------------------------------------------------------------------------------- 小结: 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的,自然排序 就是让接口所属的类实现Comparable 接口,重写compareTo(T o)方法,重写方法时,一定 要注意排序规则必须按照要求的主要条件和次要条件来写。
案例要求:存储学生对象并遍历,创建TreeSet集合使用带参构造方法。要求按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
代码实现:
public class Student{… …} //用Comparator比较器时可以不用在元素所属的类中实现Comparable接口
Public class static void main(String[] agrs){
TreeSet t = new TreeSet(new Comparator(){
//利用匿名内部类方法创建Comparator比较器作为TreeSet(Comparator comparator)的参数
@override
public int compare(Student s1,Student s2){ //注意是重写compare方法不是compareTo
int nums = s1.getId() - s2.getId();
//这是一个主要判断排序条件--按照id大小排序
int temp = nums == 0 ? s1.getName().compareTo(s2.getName()) : nums;
//这是一个次要判断排序条件--按照姓名顺序排序
return temp;
}
})
… … //与自然排序Comparable代码相同
}
-------------------------------------------------------------------------------------------------
小结:
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的比较器排
序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法,重写
方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
不重复随机数案例
要求:编写一个程序,获得10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
代码实现:
public static void main(String[]args){
Set t = new TreeSet();
//利用TreeSet给集合Set进行实例化,可让集合中的Integer元素实现自动从小到大排序
Random r = new Random(); //定义随机数类
while(t.size() < 10){
int number=r.nextInt(20)+1;
t.add(number);
}
for(Integer i : t){
System.out.print(I + " ");
}
}
注意:Set集合是接口不能直接进行实例化,可以用TreeSet、linkedHashSet、HashSet等类进行实例化。



