TreeSet集合底层才有红黑树算法,会对存储的元素默认使用自然排序(从小到大).
注意:必须保证TreeSet集合中的元素对象是相同的数据类型,否则报错.
Set<String> set1 = new TreeSet<>();
set1.add("X");
set1.add("A");
set1.add("B");
set1.add("1");
set1.add("2");
System.out.println(set1);
/*
打印结果:
[1, 2, A, B, X].
按照ascill码表排列
*/
TreeSet的排序规则
自然排序:
Tree调用集合元素的comepare方法比较元素的大小关系,然后将集合元素按照升序排列(从小到大)
注意:要求TreeSet集合中元素得实现java.util.Comparable接口.
/*
1.BigDecimal
2.BigInteger
3.Byte
4.Double
5.Float
6.Integer
7.Long
8.Short
*/
按照数字大小排列
/*
Character
*/
按照字符的Unicode值的数字大小排列
/*
String
*/
按照字符串的Unicode值排序
java.util.Comparable接口:可比较的
覆盖 public int comparaTo(Object o)方法.
在该方法中.比较当前对象(this)和参数对象o做比较(严格上说比较的是对象中的数据,比如按照对象的年龄排序)
this > o:返回正整数.1
this < o:返回负整数-1
this == o;返回0.此时认为两个对象为同一对象.
示例代码:
package com.java520.hashcodedemo;
import java.util.Set;
import java.util.TreeSet;
//记得需要遵循Comparable接口
class Person implements java.lang.Comparable<Person>{
String name;//姓名
int age;//年龄
public Person(String name,int age){
super();
this.name = name;
this.age = age;
}
public String toString(){
return "name="+this.name+",age="+this.age;
}
@Override
public int compareTo(Person other) {
if(this.age > other.age){
return 1;
}else if(this.age < other.age){
return -1;
}
return 0;
}
}
public class CompareDemo {
public static void main(String[] args) {
//按照对象的年龄做自然排序
Set<Person> set = new TreeSet<>();
set.add(new Person("李四",15));
set.add(new Person("孙三",14));
set.add(new Person("钱二",13));
set.add(new Person("赵信",12));
System.out.println(set);
//[name=赵信,age=12, name=钱二,age=13, name=孙三,age=14, name=李四,age=15]
}
}
在TreeSet的自然排序中,认为如果两个对象做比较的compare方法返回值是0,则认为是同一个对象.
定制排序(从小到大,按照名字的长短来排序):
在TreeSet构造器中传递java.lang.Comparator对象,并覆盖public int compare(Object o1,Object o2)再编写比较规则.
示例代码:
class Person{
String name;//姓名
int age;//年龄
public Person(String name,int age){
super();
this.name = name;
this.age = age;
}
public String toString(){
return "name="+this.name+",age="+this.age;
}
}
class NameLengthComparetor implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
//如果名字的长度一样,那么比较器则认为是同一个对象
if (o1.name.length() > o2.name.length()){
return 1;
}else if(o1.name.length() < o2.name.length()){
return -1;
}
return 0;
}
}
public class CompareDemo {
public static void main(String[] args) {
//按照对象的年龄做定制排序
Set<Person> set1 = new TreeSet<>(new NameLengthComparetor());
set1.add(new Person("李四1",15));
set1.add(new Person("孙三333",14));
set1.add(new Person("钱二22",13));
set1.add(new Person("赵信4444",12));
System.out.println(set1);
//[name=李四1,age=15, name=钱二22,age=13, name=孙三333,age=14, name=赵信4444,age=12]
}
}
两个排序规则可以共存,但是,对于Tree来说,要么使用自然排序,要么使用定制排序(如果真的共存了,那么以定制排序为准,详情阅读源码)
判断两个对象是否相等的规则:
- 自然排序:compareTo方法返回0;
- 定制排序:compare方法返回0;