注:我理解错了,Comparator和Comparable是根据需要进行选择的,对于一个问题,两个都可以用。
第一种方式:元素所属的类实现Comparator接口,创建集合对象时,传入一个元素所属类的对象作为比较器
import java.util.Comparator;
/*
元素所属的类实现Compararor接口,重写compare方法
*/
public class Animal implements Comparator<Animal> {
private String name;
private int age;
@Override
public String toString() {
return "Animal [name=" + name + ", 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;
}
public Animal(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Animal() {
super();
}
@Override
public int compare(Animal o1, Animal o2) {
if(o1.age!=o2.age) {
return o2.age - o1.age;
}else {
return o1.name.compareTo(o2.name);
}
}
}
public class AnimalDemo{
public static void main(String[]args){
//创建一个TreeSet集合,传入一个Comparator比较器,Animal是Comparator实现类
TreeSet<Animal> treeSet = new TreeSet<>(new Animal());//参数的Animal对象充当比较器
//添加元素
treeSet.add(new Animal("大黄", 1));
treeSet.add(new Animal("旺财", 2));
//遍历集合
Iterator<Animal> it = treeSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
第二种方式:元素所属的类不实现Comparator接口,创建集合对象是使用Comparator接口的匿名内部类
public class Animal {
private String name;
private int age;
@Override
public String toString() {
return "Animal [name=" + name + ", 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;
}
public Animal(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Animal() {
super();
}
}
public class AnimalDemo{
public static void main(String[]args){
//创建一个TreeSet集合,使用Comparator接口的匿名内部类的匿名对象作为比较器
TreeSet<Animal> treeSet = new TreeSet<>(new Comparator() {
@Override
public int compare(Animal o1, Animal o2) {
if(o1.age!=o2.age) {
return o2.age - o1.age;
}else {
return o1.name.compareTo(o2.name);
}
}
});
//添加元素
treeSet.add(new Animal("大黄", 1));
treeSet.add(new Animal("旺财", 2));
//遍历集合
Iterator<Animal> it = treeSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
一:知识点
1 TreeMap实现SortedMap(排序)接口和Marigatable(导航)接口。
2 TreeMap不允许键重复,不允许null键或null值。
3 TreeMap会自动排序
-----------------------------------------------------------------以下理解错了----------------------------------------------------------------
二实例:
1如果键是基本类型,可以直接添加键值对(默认为按键值升序排序)
import java.util.*;
public class Test {
public static void main(String[] args) {
TreeMap<Integer,String> t=new TreeMap();//默认实现了升序排序(自然排序法)
t.put(4, "a");
t.put(5, "b");
t.put(2, "c");
t.put(3, "c");
t.put(1, "c");
System.out.println(t);
}
}
输出:
{1=c, 2=c, 3=c, 4=a, 5=b}
import java.util.*;
public class Test {
public static void main(String[] args) {
TreeMap<Character,String> t=new TreeMap();//默认实现了升序排序(自然排序法)
t.put('c', "a");
t.put('f', "b");
t.put('a', "c");
t.put('b', "c");
t.put('a', "c");//在键值相同的情况下,后面的键值对会替换前面的键值对
System.out.println(t);
}
}
输出:
{a=c, b=c, c=a, f=b}
2键是基本类型,对其自定义排序规则
import java.util.*;
//要实现重新排序必须实现Comparator接口重写compare方法,重点在于返回一个整型的数
//当返回一个正整数,说明前面的数x1比后面的数x2大
//当返回一个负整数,说明前面的数x1比后面的数x2小
//当返回0,说明前面的数x1比后面的数x2相等
//一定要按照以上规则重写写这个方法
class MyComparator implements Comparator<Integer>{
public int compare(Integer x1, Integer x2) {
return -(x1-x2);//添加符号表示逆序排序
}
}
public class Test {
public static void main(String[] args) {
TreeMap<Integer,String> t=new TreeMap(new MyComparator());
//基本类型的键实现自定义排序必须写一个新类,该类实现Comparator类,重写compare()方法,
//并在创建TreeMap时,在TreeMap的方法中new该类型的对象,
t.put(2, "a");
t.put(5, "b");
t.put(4, "c");
t.put(3, "c");
t.put(1, "c");
System.out.println(t);
}
}
输出:
{5=b, 4=c, 3=c, 2=a, 1=c}
自己写的例子:
import java.util.*;
class MyComparator implements Comparator<String>{
public int compare(String x1, String x2) {
return -(x1.compareTo(x2));//实现逆序
}
}
public class Test {
public static void main(String[] args) {
TreeMap<String,Character> t=new TreeMap<>(new MyComparator());
t.put("aaa",'a');
t.put("ccc",'b');
t.put("ddd",'c');
t.put("bbb",'d');
System.out.println(t);
}
}
输出:
{ddd=c, ccc=b, bbb=d, aaa=a}
3如果键是自定义类型,在该类中直接实现Comparable接口(不用写泛型),实现compareTo(对该类的某个属性进行编写排序规则,规则同上),不用再创建TreeMaps时new该类
可以重写toString()方法[返回值是String类型]
package moon;
import java.util.*;
//在含有其他方法或属性的自定义类中要实现Comparable接口
//重写compareTo()方法
class Person implements Comparable//这里不用指定泛型
{
public Person(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Object x)//这里必须是Object不然会报错(系统自动给生成什么就是什么)
{
return this.id-((Person)x).getId();//按id升序顺序排序
}
public String toString()//注意返回值类型必须是String
{
return ""+id+" "+"name";
}
}
public class Test {
public static void main(String[] args) {
TreeMap<Person,String> t=new TreeMap<>();//这里不用在new
t.put(new Person(1,"a"),"测试1");
t.put(new Person(8,"a"),"测试2");
t.put(new Person(3,"a"),"测试3");
t.put(new Person(9,"a"),"测试4");
t.put(new Person(2,"a"),"测试5");
System.out.println(t);
//重写toString方法可以输出
//如果不重写的话,输出的键是地址
//不重写的输出方式:
Iterator it=t.entrySet().iterator();
//它的每一项都是一个Map.Entry类型的对象
while(it.hasNext())
{
Map.Entry e=(Map.Entry)it.next();
Person p=(Person)e.getKey();
String s=e.getValue().toString();
System.out.println(p.getId()+"----"+s);
}
}
}
输出:
{1 name=测试1, 2 name=测试5, 3 name=测试3, 8 name=测试2, 9 name=测试4}
1----测试1
2----测试5
3----测试3
8----测试2
9----测试4