Java 集合11 比较器Comparator

TreeSet :基于TreeMap 。可以使用元素的自然顺序对元素进行排序(元素对应的类实现Comparable 接口,重写compareTo 方法),或由Comparator集合创建时提供,这取决于所使用的构造方法
构造函数:

TreeSet(Comparator super E> comparator) //构造一个新的,空的树集,根据指定的比较器进行排序。 

**TreeSet 对元素排序有两种方法:
1.元素自身的自然排序方法,其实就是实现Comparable 接口 ,重写compareTo 方法。如果元素自身不具备自然排序,或者是具备的自然排序不是所需要的,这时只能用第二种方法。
2.比较器。其实就是在创建TreeSet 集合时,在构造函数中指定的比较方法
需要定义一个类,实现Comparator 接口,重写compare 方法**

Comparator 接口:(比较器)
强行对某个对象collection 进行整体排序的比较函数
方法:
int compare(T o1, T o2) 比较其两个参数的顺序。
boolean equals(Object obj) 指示某个其他对象是否等于此比较器。

比较器的使用
1.创建类实现Comparator 接口

package Collection;

import java.util.Comparator;

//创建类实现 Comparator  接口 实现compare 方法
public class Comparator_Beauty implements Comparator{
    @Override
    public int compare(Object o1, Object o2) {
        //类型转换
        Beauty b1 = (Beauty)o1;
        Beauty b2 = (Beauty)o2;
        //按照名字比较
        int temp=b1.getName().compareTo(b2.getName());
        return temp==0?b1.getAge()-b2.getAge():temp;
    }
}

2.在创建集合对象时,向构造函数中传入比较器对象

 //使用构造器比较//在创建集合对象时,传入构造器方法
        Set set = new TreeSet(new Comparator_Beauty());

运行结果:
chenyu1 18
chenyu3 18
chenyu5 16//按照姓名排序

小结:
1.实现Comparator 接口时,为什么没有实现 equals 方法?因为类默认的是继承 Object 类的。所以equals 方法被覆盖。同时,TreeSet 可以通过 Compare 方法来保证元素的唯一性。那么为Comparator 中定义的equals 方法有什么用?这个equals 是用来比较 两个比较器对象是否一样的。
2.为什么TreeSet 的比较方法有这两种?在TreeSet 的底层代码中,定义了 比较器的对象引用,当引用不为null 时,调用 比较器方法 compare ;当比较器为空的时候,调用自然排序的方法 compareTo
TreeSet 的使用总结:
在往集合中存储对象时,通常对象都要覆盖 hashCode ,equals ,同时实现了Comaparable 接口,建立对象的自然排序,通常还要重写 toString() 【不复写,在获取集合元素//next()时,就会调用底层的 hashCode 方法,输出哈希值】


—————————————————比较器的练习———–——————————————
一:对字符串自然排序

package Collection;
import java.util.*;
//对字符串进行排序
public class ComparatorTest_Set {
    public static void main(String[] args){
        //创建集合
        Set set = new TreeSet();
        //1.按照字符串大小排序
        set.add("ahs");
        set.add("a");
        set.add("zshd");
        set.add("fnwh");
        //获取元素
        for(Iterator it = set.iterator();it.hasNext();){
            System.out.println(it.next());
        }
    }
}

对代码内部的分析:
1.为什么可以实现排序? 字符串本身是有自己的compareTo 方法。(完成比较和保证唯一性)
2. 为什么可以实现输出串? 使用next() 方法返回的是,字符串对象。但是字符串自己有自己的toSteing() 方法。(不然输出的就是哈希值了)

二,按照长度对字符串排序
String 中的自然排序方法,无法完成所需,因此只能使用比较器

package Collection;

import java.util.Comparator;

//写字符串按照长度排序的构造器
public class ComparatorByLength_String implements Comparator{
    @Override
    public int compare(Object o1, Object o2) {
        //类型转换
        String s1= (String)o1;
        String s2= (String)o2;
        int temp= s1.length()-s2.length();//比较主要条件
        return temp==0?s1.compareTo(s2):temp;//同时要比较次要条件
    }
}
 Set set = new TreeSet(new ComparatorByLength_String());

HashSet 的索引快,如果需求为:提高唯一性元素的查询效率,还想保证有序(怎么输入就怎么输出)
LinkedHashSet:是HashSet 的子类。
哈希表和链表实现了Set接口,具有可预测的迭代次序。

代码:

package Collection;
import java.util.*;
//提高唯一性元素的查询效率,还想保证有序
//使用HashSet  的子类  LinkedHashSet
public class LinkedHashSetDemo_HashSet {
    public static void main(String[] args){
        //创建集合,不用子类的特有方法
        Set set = new LinkedHashSet();
        set.add("hdiw1");
        set.add("hdiw1");
        set.add("hdiw2");
        set.add("hdiw3");
        for(Iterator it = set.iterator();it.hasNext();){
            System.out.println(it.next());
        }
    }
}

输出结果:
hdiw1
hdiw2
hdiw3//有序,查询快,唯一
解析:
哈希表与链表的联合。其实就是在哈希表中每个元素再存下一个元素的位置,获取时按照链表的地址索引就可以按照输出的顺序。

你可能感兴趣的:(java)