无序、不重复、无索引
public class test {
public static void main(String [] args) {
Set<String> s=new HashSet<>();//创建set集合对象
s.add("张三");
s.add("李四");
s.add("王五");
System.out.println(s.add("王五"));
System.out.println(s);
}
}
Set集合所使用的方法基本上与Collection一致。
Set实现类——HashSet
采用哈希表存储数据,组成:数组+链表+红黑树。
哈希值特点:
1)如果没有重写hashcode方法,不同对象计算出的哈希值是不同的。
package test02;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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;
}
public String toString() {
return "Student{name="+name+"age="+age+"}";
}
}
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20);
Student s2=new Student("zhangsan",20);
//未重写方法
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}
2)如果已经重写hashcode方法,不同对象只要属性值相同,计算出哈希值相同。
package test02;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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 int hashCode() {
return Objects.hash(age, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
return age == other.age && Objects.equals(name, other.name);
}
public String toString() {
return "Student{name="+name+"age="+age+"}";
}
}
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20);
Student s2=new Student("zhangsan",20);
//已重写方法
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}
练习:利用HashSet集合去除重复元素
需求:创建一个存储学生对象的集合,存储多个学生对象。使用程序实现在控制台遍历该集合。
要求:学生对象的成员变量值相同,我们就认为是同一个对象
package test02;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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 int hashCode() {
return Objects.hash(age, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
return age == other.age && Objects.equals(name, other.name);
}
public String toString() {
return "Student{name="+name+",age="+age+"}";
}
}
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20);
Student s2=new Student("zhangsan",20);
Student s3=new Student("lisi",18);
Student s4=new Student("wangwu",21);
//去除重复元素,应用hashset集合,其集合有不重复性
HashSet<Student> h=new HashSet<>();
System.out.println(h.add(s1));
System.out.println(h.add(s2));
System.out.println(h.add(s3));
System.out.println(h.add(s4));
System.out.println(h);
}
}
Set实现类——LinkHashSet
有序:保证存储和取出元素一致;不重复、无索引。
底层数据结构仍是哈希表,多了一个双链表。
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20);
Student s2=new Student("zhangsan",20);
Student s3=new Student("lisi",18);
Student s4=new Student("wangwu",21);
//有序
LinkedHashSet<Student> lh=new LinkedHashSet<>();
System.out.println(lh.add(s1));
System.out.println(lh.add(s2));
System.out.println(lh.add(s3));
System.out.println(lh.add(s4));
System.out.println(lh);
}
}
Set实现类——TreeSet
不重复、无索引、可排序:按元素的默认规则(由小到大)排序。
TreeSet集合底层基于红黑树的数据结构实现排序。
TreeSet的两种比较比较方式:
1)默认排序/自然排序:javabean类实现Comparable接口指定的比较规则。
TreeSet对象排序练习题:创建TreeSet集合,并添加3个学生对象学生对象属性:姓名,年龄。
要求按照学生的年龄进行排序,同年龄按照姓名字母排列( 暂不考虑中文)同姓名,同年龄认为是同一个人。
package test02;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name,int age) {
this.setName(name);
this.setAge(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 int hashCode() {
return Objects.hash(age, name);
}
public String toString() {
return "Student{name="+name+",age="+age+"}";
}
@Override
public int compareTo(Student o) {//排序规则
return this.getAge()-o.getAge();
//this表示当前要添加的元素
//o表示已经在红黑树中的元素
//返回值:
//负数:认为添加的元素小,存左边
//正数:认为添加的元素大,存右边
//0:认为添加的元素已经存在,舍弃
}
}
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20);
Student s2=new Student("zhangsan",20);
Student s3=new Student("lisi",18);
Student s4=new Student("wangwu",21);
TreeSet<Student> t=new TreeSet<>();
System.out.println(t.add(s1));
System.out.println(t.add(s2));
System.out.println(t.add(s3));
System.out.println(t.add(s4));
System.out.println(t);
}
}
2)比较器排序:创建TreeSet对象时,传递比较器Comparator指定规则。
默认使用第一种排序,第一种不满足使用第二种。
要求:存入四个字符串,“c” "ab" “df”,' qwer',按照长度排序,如果一样长则按照首字母排序.
使用比较器排序:
public class test {
public static void main(String [] args) {
TreeSet<String> ts=new TreeSet<>(new Comparator<String>() {
public int compare(String o1,String o2) {
int i=o1.length()-o2.length();
i=i==0? o1.compareTo(o2):i;
return i;
}
});
ts.add("c");
ts.add("ab");
ts.add("df");
ts.add("qwer");
System.out.println(ts);
}
}
练习:TreeSet对象排序练习题
需求:创建5个学生对象
属性: (姓名,年龄,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
如果总分一样,按照语文成绩排
如果语文一样,按照数学成绩排
如果数学成绩一样,按照英语成绩排
如果英文成绩一-样,按照年龄排
如果年龄一样,按照姓名的字母顺序排
如果都一样,认为是同一一个学生,不存。
package test02;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
private int math;
private int chinese;
private int English;
public Student() {
}
public Student(String name,int age,int math,int chinese,int English) {
this.setName(name);
this.setAge(age);
this.setMath(math);
this.setChinese(chinese);
this.setEnglish(English);
}
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;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getEnglish() {
return English;
}
public void setEnglish(int english) {
English = english;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", math=" + math + ", chinese=" + chinese + ", English="
+ English + "]";
}
@Override
public int compareTo(Student o) {//排序规则
//
int sum1=this.getChinese()+this.getEnglish()+this.getMath();
int sum2=o.getChinese()+o.getEnglish()+o.getMath();
int i=sum1-sum2;
//如果总分一样,按语文成绩排
i=i==0 ? this.getChinese()-o.getChinese():i;
//数学成绩
i=i==0 ? this.getMath()-o.getMath():i;
//英语成绩
i=i==0 ?this.getEnglish()-o.getEnglish():i;
//如果英语成绩一样,按年龄排
i=i==0 ? this.getAge()-o.getAge():i;
//如果年龄一样,按姓名字母顺序排
i=i==0 ?this.getName().compareTo(o.getName()):i;
return i;
}
}
public class test {
public static void main(String [] args) {
Student s1=new Student("zhangsan",20,88,88,89);
Student s2=new Student("qingliu",20,88,88,89);
Student s3=new Student("lisi",18,88,85,90);
Student s4=new Student("wangwu",21,90,91,92);
TreeSet<Student> t=new TreeSet<>();
System.out.println(t.add(s1));
System.out.println(t.add(s2));
System.out.println(t.add(s3));
System.out.println(t.add(s4));
System.out.println(t);
}
}