一、HashSet
1,描述
(1)元素唯一
(2)元素无序(存储和取出不一致)
2,如何实现元素的唯一
(1)自定义元素唯一性的规则
(2)在元素所属对象类中重写hashCode(),equals()方法
3,应用案例
需求:产生10个[1-20]之间的随机数,要求不能重复
import java.util.HashSet; import java.util.Random; /** * @author Manduner_TJU * @version 创建时间:2018年6月7日下午10:34:02 */ public class HashSetDemo { public static void main(String[] args) { //创建Random对象 Random r = new Random(); //创建HashSet HashSet<Integer> hs = new HashSet<Integer>(); //创建随机数并存入HashSet集合 while(hs.size() < 10) { Integer i = r.nextInt(20) + 1; hs.add(i); } //遍历 for(Integer i : hs) { System.out.println(i); } } }
二、LinkedHashSet
1,描述
(1)底层 数据结构由哈希表和链表组成
(2)哈希表保证元素的唯一性
(3)链表保证元素有序(存储和取出一致)
2,应用案例
import java.util.LinkedHashSet; public class LinkedHashSetDemo { public static void main(String[] args) { LinkedHashSet<String> hs = new LinkedHashSet<String>(); hs.add("my"); hs.add("name"); hs.add("manduener"); hs.add("manduener"); hs.add("name"); // 遍历 for (String s : hs) { System.out.println(s); } } }
三、TreeSet
1,描述
(1)元素唯一
(2)能够对元素按照某种规则进行排序
1)自然排序
i、使用TreeSet的无参构造方法
ii、让元素所属的类实现自然排序接口 Comparable
2)比较器排序
i、使用TreeSet的带参构造方法
ii、让集合的构造方法接收一个比较器接口的子类对象 Comparator
(3)底层结构是红黑树
1)有自平衡的特点
2)遍历采用中序遍历的方法,即左、根、右,以达到集合元素按序取出
2,应用案例一:自然排序
需求:使用TreeSet存储自定义的Student对象,并按照Student对象中学生姓名的长度排序。Student类的定义以及TreeSet的实现如下。
Student类
/** * @author Manduner_TJU * @version 创建时间:2018年6月6日下午9:37:34 */ //Student类继承了Comparable<Student>后,TreeSet集合在添加元素的时候会根据重写的compareTo方法,对所添加元素进行去重, //并会以自定义的排序要求,将元素以红黑数的形式存放起来 public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { super(); 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 int compareTo(Student s) { // TODO Auto-generated method stub //return 0; //根据需求,计算待添加元素和TreeSet中已有元素的长度差值 int num = this.getName().length() - s.getName().length(); if(num == 0) { //如果长度一样,需要进一步作出如下判断 if(this.getName().equals(s.getName())) { //如果名字一样,并且是同一个人,需要再判断年龄是否是一样的 num = this.getAge() - s.getAge(); } else { //如果名字不一样,按字典顺序比较两个字符串 num = this.getName().compareTo(s.getName()); } } //如果名字长度不一样,则将新来元素直接添加到TreeSet中 return num; } }
实现类
import java.util.TreeSet; import user.Student; /** * @author Manduner_TJU * @version 创建时间:2018年6月6日下午9:43:47 */ public class TreeSetDemo { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(); Student s1 = new Student("baiqi",38); Student s2 = new Student("yingji",30); Student s3 = new Student("baiqi",38); Student s4 = new Student("qinhuiwenwang",60); Student s5 = new Student("minyue",25); Student s6 = new Student("baiqi",26); Student s7 = new Student("laiyy",26); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); //增强for遍历集合 //当没有指定TreeSet集合按照什么规则去重和排序时,会有如下错误: //java.lang.ClassCastException: user.Student cannot be cast to java.lang.Comparable //错误的意思表示:需要在Student类中实现Comparable,并重写compareTo方法 for(Student s : ts) { System.out.println(s.getName()+" "+s.getAge()); } } }
3,应用案例二:比较器排序
需求:使用TreeSet存储自定义的Student对象,并按照Student对象中学生姓名的长度排序。Student类的定义以及TreeSet的实现如下。
Student类
public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); 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; } }
实现类(注:Java8中已经没有匿名内部类和局部内部类了,所以下面这段代码不能在java8中运行)
public class TreeSetDemo { public static void main(String[] args) { // 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象 // 而匿名内部类就可以实现这个东西 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // 姓名长度 int num = s1.getName().length() - s2.getName().length(); // 姓名内容 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; // 年龄 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; return num3; } }); Student s1 = new Student("baiqi",38); Student s2 = new Student("yingji",30); Student s3 = new Student("baiqi",38); Student s4 = new Student("qinhuiwenwang",60); Student s5 = new Student("minyue",25); Student s6 = new Student("baiqi",26); Student s7 = new Student("laiyy",26); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); // 遍历 for (Student s : ts) { System.out.println(s.getName() + " " + s.getAge()); } } }