1. TreeSet
collection
下面有:
List
:元素的有序的,元素可以重复,因为该集合体系有索引
______ArrayList
:底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删速度慢
______LinkedList
:底层的数据结构使用的是链表结构。特点:查询速度慢,但是增删速度快
______Vector
:底层的数据结构使用的是数组结构,线程同步,被ArrayList替代了
Set
: 元素是无序,元素不可以重复
______HashSet
:底层的数据结构使用的是哈希表。保证元素的唯一性的原理:判断元素的HashCode值是否相同。如果相同,还会继续判断元素的equals方式,是否为true
______TreeSet
:特点:可以对Set集合中的元素进行排序。使用红黑树存储(二叉排序树),读取的时候中序遍历
package collectionDemo;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add("ab");
treeSet.add("aa");
treeSet.add("bc");
treeSet.add("bb");
Iterator it = treeSet.iterator();
while (it.hasNext()){
sop(it.next());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
输出:
aa
ab
bb
bc
2. TreeSet存储自定义对象
需求:
往TreeSet集合中存储自定义对象学生,按照学生的年龄进行排序。
package collectionDemo;
import java.util.Iterator;
import java.util.TreeSet;
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(new Student("shh01",21));
treeSet.add(new Student("shh02",22));
treeSet.add(new Student("shh03",23));
treeSet.add(new Student("shh04",24));
Iterator it = treeSet.iterator();
while (it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
结果(出现异常,学生类不具备比较性):
Exception in thread "main" java.lang.ClassCastException: collectionDemo.Student cannot be cast to java.base/java.lang.Comparable
at java.base/java.util.TreeMap.compare(TreeMap.java:1291)
at java.base/java.util.TreeMap.put(TreeMap.java:536)
at java.base/java.util.TreeSet.add(TreeSet.java:255)
at collectionDemo.TreeSetDemo1.main(TreeSetDemo1.java:38)
解决方法:让学生类实现Comparable接口,让学生具备比较性。
package collectionDemo;
import java.util.Iterator;
import java.util.TreeSet;
class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int compareTo(Object obj){
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student student = (Student)obj;
System.out.println(this.name+"......compareTo......"+student.name);
if(this.age > student.age) return 1;
else if(this.age == student.age) //主要条件比较
return this.name.compareTo(student.getName()); // 次要条件比较
else return -1;
}
}
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(new Student("shh01",21));
treeSet.add(new Student("shh02",20));
treeSet.add(new Student("shh03",19));
treeSet.add(new Student("shh04",19));
Iterator it = treeSet.iterator();
while (it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
结果:
shh01......compareTo......shh01
shh02......compareTo......shh01
shh03......compareTo......shh01
shh03......compareTo......shh02
shh04......compareTo......shh02
shh04......compareTo......shh03
shh03...19
shh04...19
shh02...20
shh01...21
记住: 排序时,当主要条件相同时,一定要判断一下次要条件。
3. 二叉树
collection
下面有:
List
:元素的有序的,元素可以重复,因为该集合体系有索引
______ArrayList
:底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删速度慢
______LinkedList
:底层的数据结构使用的是链表结构。特点:查询速度慢,但是增删速度快
______Vector
:底层的数据结构使用的是数组结构,线程同步,被ArrayList替代了
Set
: 元素是无序,元素不可以重复
______HashSet
:底层的数据结构使用的是哈希表。保证元素的唯一性的原理:判断元素的HashCode值是否相同。如果相同,还会继续判断元素的equals方式,是否为true
______TreeSet
:特点:可以对Set集合中的元素进行排序。底层数据结构是二叉树。保证元素唯一性的依据,compareTo方法返回0.
TreeSet排序的第一种方式:让元素自身具有比较性。
元素需要实现Comparable接口,覆盖compareTo方法,这种方式也被称为元素的自然顺序,或者被叫做默认顺序。
4. 实现comparetor方式排序
TreeSet排序的第二种方式:当元素自身不具备比较性,或者具备的比较性不是所需要的,这是就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主
定义一个类,实现Comparator接口,覆盖compare方法
实例:将姓名作为比较的条件,让容器具有比较性。
package collectionDemo;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
class MyCompare implements Comparator { // 实现比较器接口
public int compare(Object obj1, Object obj2){
Student st1 = (Student)obj1;
Student st2 = (Student)obj2;
int num = st1.getName().compareTo(st2.getName());
if(num == 0) return st1.getAge()-st2.getAge();
return num;
}
}
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet(new MyCompare());
treeSet.add(new Student("shh01",21));
treeSet.add(new Student("shh02",20));
treeSet.add(new Student("shh05",19));
treeSet.add(new Student("shh04",19));
treeSet.add(new Student("shh04",12));
Iterator it = treeSet.iterator();
while (it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
结果:
shh01...21
shh02...20
shh04...12
shh04...19
shh05...19
5. TreeSet练习题
练习:按照字符串的长度排序
分析: 字符串本身具备比较性,但是它的比较方式不是所需要的,这时就只能使用比较器。
package collectionDemo;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
class StringLengthComparator implements Comparator{
public int compare(Object obj1, Object obj2){
String s1 = (String)obj1;
String s2 = (String)obj2;
int len1 = s1.length(), len2 = s2.length();
int num = len1-len2;
if(num == 0)
return s1.compareTo(s2);
return num;
}
}
public class TreeSetTest {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet(new StringLengthComparator());
// 使用含有参数的构造函数,使集合在初始化的时候带有比较器。
treeSet.add("abc");
treeSet.add("abcdf");
treeSet.add("bcdef");
treeSet.add("bcd");
Iterator it = treeSet.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
结果:
abc
bcd
abcdf
bcdef