java中TreeSet或者TreeMap实现自定义对象的排序

java中TreeSet或者TreeMap实现自定义对象的排序


TreeSet和TreeMap底层都是以二叉树为数据结构,TreeSet在存放引用类型的数据或者TreeMap以引用类型为键值时,需要让需要排序的对象所处的类实现Comparable接口 或者在构造这两个的集合的时候使用带比较器的构造方法。

//	定义学生类,实现Comparable接口
//	并复写compareTo方法,使学生具有比较这个行为
class Student  implements Comparable<Student> {
     
	int id;//	学生id
	String name;//	学生姓名
	int cScore;//	语文成绩
	int mScore;//	数学成绩
	int eScore;//	英语成绩
	//	构造方法
	public Student(int id, String name, int cScore, int mScore, int eScore) {
     
		this.id = id;
		this.name = name;
		this.cScore = cScore;
		this.mScore = mScore;
		this.eScore = eScore;
	}
	@Override 
	//	按学生总成绩从高到低排序,成绩相同的,按照id大小升序排序
	public int compareTo(Student o) {
     
		int s1 = this.cScore + this.mScore + this.eScore;
		int s2 = o.cScore + o.mScore + o.eScore;
		return s1 == s2 ? (this.id - o.id) : (s2 - s1);
	}
}
public class StudentDemo {
     

	public static void main(String[] args) {
     
		//	方式1,直接存放已经具备比较能力的学生对象
		TreeSet<Student> ts1 = new TreeSet<>();//	第二个尖括号可以省略
		ts1.add(100, "小吴", 78, 90, 80);
		ts1.add(104, "小王", 100, 100, 90);
		ts1.add(105, "小张", 100, 100, 90);
		//	方式2,使用带比较器的TreeSet
		//	new的是接口,但是要记得重写方法,也可以new一个实现了Comparator比较器的类,但在那个类中同样要复写接口中的方法。
		TreeSet<Student> ts2 = new TreeSet<Student>(new Comparator<Student>() {
     
			public int compare(Student p1, Student p2) {
     
				int s1 = p1.cScore + p1.mScore + p1.eScore;
				int s2 = p2.cScore + p2.mScore + p2.eScore;
				return s1 == s2 ? (p1.id - p2.id) : (s2 - s1);
			}
		});
	    //	方式二还有另外一种写法,这是java8新增的Lambda表达式,可以省略大部分固定的代码
		TreeSet<Student> ts3 = new TreeSet<>((o1,o2) -> {
     
			int s1 = o1.cScore + o1.mScore + o1.eScore;
			int s2 = o2.cScore + o2.mScore + o2.eScore;
			return s1 == s2 ? (o1.id - o2.id) : (s2 - s1);
		});
		

HashMap的使用和HashSet的自定义对象比较方法是一样的,这里不再赘述。

你可能感兴趣的:(Java入门教程,java,lambda)