键值:Map集合等;
单值存储:数组,List,Set,Queue集合等;
我们知道部分的集合实现的原理不用,比如TreeMap底层采用红黑树,实现了排序的功能,其默认排序一般为从小到大排序数字,根据字典序排序字符等,但默认排序方式因为缺陷往往不能满足开发的需求,因此必须自己学会如何实现自定义比较器;
TreeSet与TreeMap可以代表大部分集合实现自定义比较器的操作,因此以TreeSet与TreeMap为例;
1.TreeMap部分源码;
// 调用compare比较两个key值
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
final int compare(Object k1, Object k2) {
// 调用默认的比较器,实现默认排序
return comparator==null ? ((Comparable super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
2.测试以Integer为键类型的默认排序;
package test;
import java.util.Map.Entry;
import java.util.TreeMap;
public class MyTreeMap {
//public static TreeMap studentMap = new TreeMap<>();
public static TreeMap intergerMap = new TreeMap<>();
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 10; i > 0; --i) {
//studentMap.put(new Student(i, "小王" + i), i);
intergerMap.put(i, new Student(i, "小王" + i));
}
// 打印集合中的元素
while(!intergerMap.isEmpty()) {
Entry firstEntry = intergerMap.pollFirstEntry();
System.out.println(firstEntry.getValue().toString());
}
}
}
class Student {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
}
// 输出结果
/*
Student [age=1, name=小王1]
Student [age=2, name=小王2]
Student [age=3, name=小王3]
Student [age=4, name=小王4]
Student [age=5, name=小王5]
Student [age=6, name=小王6]
Student [age=7, name=小王7]
Student [age=8, name=小王8]
Student [age=9, name=小王9]
Student [age=10, name=小王10]
*/
由默认排序结果可以看出,IntegerMap根据键(Interger)从小到大进行排序;
3.自定义比较器,根据键从大到小进行排序
1.初始化TreeMap时实现匿名内部类Comparator,实现根据Interger键从大到小排序
package test;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMap {
public static TreeMap intergerMap = new TreeMap<>(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
Integer integer1 = (Integer)01;
Integer integer2 = (Integer)o2;
return integer1 > integer2? 1:-1;
}
});
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 1; i < 11; ++i) {
//studentMap.put(new Student(i, "小王" + i), i);
intergerMap.put(i, new Student(i, "小王" + i));
}
// 打印集合中的元素
while(!intergerMap.isEmpty()) {
Entry firstEntry = intergerMap.pollFirstEntry();
System.out.println(firstEntry.getValue().toString());
}
}
}
class Student {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
}
// 测试结果
/*
Student [age=10, name=小王10]
Student [age=9, name=小王9]
Student [age=8, name=小王8]
Student [age=7, name=小王7]
Student [age=6, name=小王6]
Student [age=5, name=小王5]
Student [age=4, name=小王4]
Student [age=3, name=小王3]
Student [age=2, name=小王2]
Student [age=1, name=小王1]
*/
2.初始化TreeMap时,将comparator的实现类进行传参,实现根据Interger从大到小排序;
package test;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMap {
static MyCompare com = new MyCompare();
public static TreeMap intergerMap = new TreeMap<>(com);
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 1; i < 11; ++i) {
//studentMap.put(new Student(i, "小王" + i), i);
intergerMap.put(i, new Student(i, "小王" + i));
}
// 打印集合中的元素
while(!intergerMap.isEmpty()) {
Entry firstEntry = intergerMap.pollFirstEntry();
System.out.println(firstEntry.getValue().toString());
}
}
}
class Student {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
}
class MyCompare implements Comparator
4.键为对象时,进行自定义排序
1.student对象实现compare接口的compareTo方法,根据age从大到小排序;
package test;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMap {
public static TreeMap studentMap = new TreeMap<>();
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 1; i < 11; ++i) {
studentMap.put(new Student(i, "小王" + i), i);
}
// 打印集合中的元素
while(!studentMap.isEmpty()) {
Entry firstEntry = studentMap.pollFirstEntry();
System.out.println(firstEntry.getKey().toString());
}
}
}
class Student implements Comparable
2.初始化是实现匿名内部类Comparator,实现根据age从大到小排序
package test;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMap {
public static TreeMap studentMap = new TreeMap<>(new Comparator() {
@Override
public int compare(Student o1, Student o2) {
Student student1 = (Student)o1;
Student student2 = (Student)o2;
return student1.age < student2.age? 1 : -1;
}
});
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 1; i < 11; ++i) {
studentMap.put(new Student(i, "小王" + i), i);
}
// 打印集合中的元素
while(!studentMap.isEmpty()) {
Entry firstEntry = studentMap.pollFirstEntry();
System.out.println(firstEntry.getKey().toString());
}
}
}
class Student {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
/*
Student [age=10, name=小王10]
Student [age=9, name=小王9]
Student [age=8, name=小王8]
Student [age=7, name=小王7]
Student [age=6, name=小王6]
Student [age=5, name=小王5]
Student [age=4, name=小王4]
Student [age=3, name=小王3]
Student [age=2, name=小王2]
Student [age=1, name=小王1]
*/
}
3. 初始化TreeMap时,将comparator的实现类进行传参,实现根据Interger从大到小排序;
package test;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeMap;
public class MyTreeMap {
static Mycompare cMycompare = new Mycompare();
public static TreeMap studentMap = new TreeMap<>(cMycompare);
public static void main(String[] args) {
// 给集合中添加10个student对象
for (int i = 1; i < 11; ++i) {
studentMap.put(new Student(i, "小王" + i), i);
}
// 打印集合中的元素
while(!studentMap.isEmpty()) {
Entry firstEntry = studentMap.pollFirstEntry();
System.out.println(firstEntry.getKey().toString());
}
}
}
class Student {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
}
class Mycompare implements Comparator
TreeSet的底层实现相似于TreeMap,可以将TreeSet看作TreeMap的vlalue值为object,而TreeSet值可以认为TreeMap的键,依次可以知道,TreeSet的比较用法;
1.当要排序的对象实现目标为基本类型时
2.当要排序的对象实现目标为对象时
3.以上为简单的总结,实际的开发中,比较器的构造比较灵活,大家根据情况实现;