上一章简单介绍了Desktop桌面类的使用(十),如果没有看过,请观看上一章
一. 比较接口
在Java 中, 有普通数值的比较 ,如比较运算符 > < , 3>4, 也有字符串的比较值, 如String 类中的compare() 方法, 当然也有对象之间的比较。 对象之间的比较 用到的是Comparable 接口或者是 Comparator 接口。
其中, Comparable 接口的定义是:
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
只有一个 compare() 的方法,是自身的比较。
Comparator 接口的定义是:
package java.util;
import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;
@FunctionalInterface
public interface Comparator<T> {
//主要接口.
int compare(T o1, T o2);
boolean equals(Object obj);
}
现在,创建一个用户类 User, 里面有 年龄和成绩的属性, 根据成绩和年龄进行相应的排序。
先按照 成绩从高到低排序,如果成绩一样,那么就按照年龄排序,年龄小的在前面。
二. 创建类 User
package com.yjl.compa;
/**
@atuhor:两个蝴蝶飞
@Description: 类User
*/
public class User {
/**
* @param id id编号
* @param name 姓名
* @param age 年龄
* @param score 成绩
* @param description 描述
*/
private int id;
private String name;
private int age;
private double score;
private String description;
public User(int id, String name, int age, double score, String description) {
super();
this.id = id;
this.name = name;
this.age = age;
this.score = score;
this.description = description;
}
public User(){
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + ", score=" + score + ", description="
+ description + "]";
}
}
三. Comparable 接口的使用
三.一 让比较类 User 实现 Comparable 接口
public class User implements Comparable<User>{
}
三.二 重写 comareTo() 接口。
@Override
public int compareTo(User user) {
if(this.score>user.score){
return -1;
}else if(this.score<user.score){
return 1;
}else{ //成绩相同,按照年龄进行排序
if(this.age>user.age){
return 1;
}else if(this.age<user.age){
return -1;
}else{
return 0;
}
}
}
这样的话, 这个用户类 User 就可以进行比较了。 会先按照成绩进行排序,再按照年龄排序。
三.三 测试方法 用数组测试
package com.yjl.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.yjl.compa.MyComparator;
import com.yjl.compa.StringComparator;
import com.yjl.compa.User;
/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class CompaTest {
private List<User> allUser=new ArrayList<User>();
private User[] allArr=null;
@Before
public void initUserList(){
User user1=new User(1,"蝴蝶飞",24,98.0,"这是蝴蝶飞");
User user2=new User(2,"两个蝴蝶飞",24,99.0,"这是两个蝴蝶飞");
User user3=new User(3,"精灵妹",24,100.0,"这是精灵妹");
User user4=new User(4,"精灵",24,97.0,"这是精灵");
User user5=new User(5,"张三",25,98.0,"这是张三");
User user6=new User(6,"李四",25,99.0,"这是李四");
User user7=new User(7,"驭风",25,100.0,"这是驭风");
User user8=new User(8,"墨",25,97.0,"这是墨");
User user9=new User(9,"周",25,96.0,"这是周");
allUser.add(user1);
allUser.add(user2);
allUser.add(user3);
allUser.add(user4);
allUser.add(user5);
allUser.add(user6);
allUser.add(user7);
allUser.add(user8);
allUser.add(user9);
//转换成数组
allArr=allUser.toArray(new User[]{});
}
@Test
public void testA(){
// System.out.println(allArr.length); //有值,9,说明转换成功。
System.out.println("排序之前输出:");
for(User u:allArr){
System.out.println(u);
}
Arrays.sort(allArr); /*从小到大排*/
System.out.println("排序之后输出:");
for(User u:allArr){
System.out.println(u);
}
}
}
日志输出:
排序之前,是按照 id 编号 进行输出,排序之后, 会按照成绩 和年龄进行相应的排序。
四. Comparator 接口
User 类 保持不变,与第二步的 User 一样,是一个简单的User 类。
四.一 新建新的排序类,实现 Comparator 接口
新建一个MyComparator 的类, 实现接口,重写里面的comparator 方法。
package com.yjl.compa;
import java.util.Comparator;
/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class MyComparator implements Comparator<User>{
@Override
public int compare(User u1, User u2) {
if(u1.getScore()>u2.getScore()){
return -1;
}else if(u1.getScore()<u2.getScore()){
return 1;
}else{ //成绩相同,按照年龄进行排序
if(u1.getAge()>u2.getAge()){
return 1;
}else if(u1.getAge()<u2.getAge()){
return -1;
}else{
return 0;
}
}
}
}
四.二 测试方法 用集合测试
package com.yjl.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.yjl.compa.MyComparator;
import com.yjl.compa.StringComparator;
import com.yjl.compa.User;
/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class CompaTest {
private List<User> allUser=new ArrayList<User>();
private User[] allArr=null;
@Before
public void initUserList(){
User user1=new User(1,"蝴蝶飞",24,98.0,"这是蝴蝶飞");
User user2=new User(2,"两个蝴蝶飞",24,99.0,"这是两个蝴蝶飞");
User user3=new User(3,"精灵妹",24,100.0,"这是精灵妹");
User user4=new User(4,"精灵",24,97.0,"这是精灵");
User user5=new User(5,"张三",25,98.0,"这是张三");
User user6=new User(6,"李四",25,99.0,"这是李四");
User user7=new User(7,"驭风",25,100.0,"这是驭风");
User user8=new User(8,"墨",25,97.0,"这是墨");
User user9=new User(9,"周",25,96.0,"这是周");
allUser.add(user1);
allUser.add(user2);
allUser.add(user3);
allUser.add(user4);
allUser.add(user5);
allUser.add(user6);
allUser.add(user7);
allUser.add(user8);
allUser.add(user9);
//转换成数组
allArr=allUser.toArray(new User[]{});
}
@Test
public void testB(){
System.out.println("排序之前:");
allUser.forEach(n ->System.out.println(n));
allUser.sort(new MyComparator());
System.out.println("排序之后:");
allUser.forEach(n ->System.out.println(n));
}
}
控制台输出为:
可以正常的排序。
五. Comparable 和Comparator 接口的区别
- Comparable 接口 实现简单, 直接 在实体类中 实现 该接口,重写里面的规则方法即可,而Comparator 接口却需要新建一个类,才重新该方法。
- Comparable 是内比较器,是这个类的 当前对象与另外一个对象进行比较,而Comparator 是外比较器, 是某个类 的两个不同的对象进行比较。
- Comparable 一般用于 创建类的同时 进行创建排序规则, 而Comparator 是类创建完成之后好久,需求改变排序。
- 改变时,如果Comparable 时,想要改变规则,如按照名称和年龄进行排序,则需要修改 User 中compareTo 的代码实现,而Comparator 不需要,只需要新建一个名称和年龄的排序类即可,然后在集合排序时,将这个名称和年龄的类放入进去即可。适用于可能存在多个规则的情况下。
建议使用 Comparator 接口。
谢谢!!!