首页 > 代码库 > Collection —— Set集合
Collection —— Set集合
第二部分(Set)
Set接口 ———— 继承Collection
1、Set集合(是一个不可有重复元素的Collection)
1)Set集合的特点:是无序的(存储和取出不一致),集合中的元素不可以重复
2)Set子实现类的特点
HashSet
它不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变且元素不可以重复
LinkedHashSet(HashSet的子类)
底层数据结构是由哈希表和链表实现,所以它是有序的且元素不可以重复
TreeSet
底层数据结构是一种红黑树数据结构,保证元素的唯一性并且排序
2、HashSet类
1)概述:此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持
2)唯一性(不可重复性)
HashSet的add方法,底层依赖于HashMap的put(Key,Value)方法
首先判断它们的hash(),底层是调用HashCode()方法
如果HashCode():哈西码值一样,
然后在比较他们的内容是否相同(equals()方法)
所以在使用时,为了保证Set的不可重复性,需要重写所存储元素的HashCode()和equals()方法。
3)此类允许使用 null 当做元素
4)LinkedHashSet类 ———— 继承HashSet
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现类
哈希表:保证元素的唯一性
链表:元素的存储和取出一致(有序性)
3、TreeSet类
有两种排序方式:
1)红黑树结构储存和取出元素的特点————基于TreeMap
储存:将第一个存储的元素作为根节点,其后元素与其作比较,大了作为右孩子放右边,小了作为左孩子放左边
取出:前序遍历,中序遍历,后序遍历,依次取每一个元素的值
2)第一种排序方式:自然排序
需要集合中存储元素所在的类实现(implements)Comparable接口,重写compareTo()方法;
在基本数据的包装类中他们已经实现接口并重写了compareTo()方法,所以可以直接使用;
String中重写的compareTo()方法:(与红黑树结构的储存一致)
public int compareTo(String anotherString):按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。
如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
如果这两个字符串相等,则结果为 0;
egg:
import java.util.TreeSet;
//需求:请按照姓名的长度排序
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
ts.add(new Student("zhaoyun", "七进七出"));
ts.add(new Student("zhangfei", "当阳怒吼"));
ts.add(new Student("guanyu", "水淹七军"));
ts.add(new Student("zhugeliang", "七擒孟获"));
ts.add(new Student("luxun", "火烧连营"));
ts.add(new Student("liubei","白帝托孤"));
for(Student s : ts){
System.out.println(s.getName() + "-----" + s.getStory());
}
}
}
public class Student implements Comparable<Student>{
private String name;
private String story;
//有参无参构造器;
//get()set()方法;
@Override
public int compareTo(Student o) {
int num = this.getName().length() - o.getName().length(); //姓名短的放前面,长的放后面
int num2 = num == 0 ? this.getStory().compareTo(o.getStory()) : num; //如果姓名长度一样,比较story是否一样
return num2;
}
}
3)第二种排序方式:比较器排序
在创建TreeSet对象的时候,使用TreeSet(Comparator<? super E> comparator)构造方法传入一个Comparator接口的子实现类对象,在子实现类中重写int compare(T o1, T o2)方法;
可以通过创建一个Comparator的子实现类或者使用匿名内部类来完成(推荐使用匿名内部类)
compare(T o1,T o2)方法就相当于compareTo(T t)方法,返回负值就把o2放到o1的后头,返回正值就把o2放01的前头
egg:
import java.util.Comparator;
import java.util.TreeSet;
//根据字符串的长度排序,长的在前
public class TreeSetTest2 {
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int num = o2.length() - o1.length();
int num2 = num == 0 ? o1.compareTo(o2) : num;
return num2;
}
});
ts.add("aa");
ts.add("aaa");
ts.add("aab");
ts.add("aab");
ts.add("aabdf");
for(String s : ts){
System.out.println(s);
}
}
}
4、练习
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/*
* 1:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet<Students> ts = new TreeSet<Students>(new Comparator<Students>() {
@Override
public int compare(Students o1, Students o2) {
int sub1 = Integer.parseInt(o1.getChinese()) + Integer.parseInt(o1.getMath())
+ Integer.parseInt(o1.getEnglish());
int sub2 = Integer.parseInt(o2.getChinese()) + Integer.parseInt(o2.getMath())
+ Integer.parseInt(o2.getEnglish());
int num = sub2 - sub1;
int num2 = num == 0 ? o1.getName().compareTo(o1.getName()) : num;
return num2;
}
});
Scanner sc = new Scanner(System.in);
for(int i = 1;i <= 5;i++){
Students s = new Students();
System.out.println("请输入第" + i + "个学生姓名:");
s.setName(sc.nextLine());
System.out.println("请输入第" + i + "个学生的语文成绩:");
s.setChinese(sc.nextLine());
System.out.println("请输入第" + i + "个学生的数学成绩:");
s.setMath(sc.nextLine());
System.out.println("请输入第" + i + "个学生的英语成绩:");
s.setEnglish(sc.nextLine());
ts.add(s);
}
for(Students s : ts){
System.out.println("学生姓名:" + s.getName() + "\t语文成绩:" + s.getChinese()
+ "\t数学成绩:" + s.getMath() + "\t英语成绩:" + s.getEnglish()
+ "\t总分:" + (Integer.parseInt(s.getChinese()) + Integer.parseInt(s.getMath())
+ Integer.parseInt(s.getEnglish())));
}
}
}
public class Students {
private String name;
private String chinese;
private String math;
private String english;
//有参、无参构造器
//set()get()方法
}
Collection —— Set集合