大家好,今天小编来为大家解答以下的问题,关于Java对象自定义排序技巧与实现方法,这个很多人还不知道,现在让我们一起来看看吧!
可比较简介
类似的是排序界面。
如果一个类实现了Comparable接口,就意味着“这个类支持排序”。
由于实现Comparable接口的类支持排序,假设现在有一个“实现Comparable接口的类的对象的List(或数组)”,则可以将List(或数组)传递给
Collections.sort(或Arrays.sort)进行排序。
可比较的定义
Comparable接口只包含一个函数,其定义如下:
包java.lang;导入java.util.*;
公共接口可比较{
公共int CompareTo(T o);
}
阐明:
假设我们使用x.compareTo(y) 来“比较x 和y 的大小”。如果返回“负数”,则表示“x小于y”;如果返回“零”,则表示“x 等于y”;如果返回“正数”,则表示“x 大于y”。
比较器简介
比较器是比较器接口。
如果我们需要控制某个类的顺序,而该类本身不支持排序(即没有实现Comparable接口);然后,我们可以创建一个“此类的比较器”来执行排序。这个“比较器”只需要实现Comparator接口即可。
换句话说,我们可以通过“实现Comparator类”来创建一个新的比较器,然后通过这个比较器对类进行排序。
比较器定义
Comparator接口只包含两个函数,定义如下:
包java.util;
公共接口比较器{
int 比较(T o1,T o2);
布尔等于(对象obj);
}
阐明:
(01) 如果一个类要实现Comparator接口:必须实现compare(T o1, To2)函数,但不需要实现equals(Object obj)函数。
为什么不能实施呢?
equals(Object obj) 函数怎么样?因为任何类都默认实现了equals(Object obj) 。
Java中的所有类都继承自java.lang.Object,并且equals(Object
obj) 函数;因此,所有其他类都等效于实现此功能。
(02) intcompare(T o1, To2) 是“比较o1和o2的大小”。返回“负数”表示“o1小于o2”;返回“零”意味着“o1 等于o2”;返回“正数”意味着“o1 大于o2”。
比较器和Comparable比较
Comparable是一个排序接口;如果一个类实现了Comparable接口,则意味着“这个类支持排序”。
比较器是比较器;如果我们需要控制某个类的顺序,我们可以创建一个“该类的比较器”来进行排序。
我们不难发现Comparable相当于“内部比较器”,Comparator相当于“外部比较器”。
我们通过一个测试程序来说明这两个接口。源码如下:
导入java.util.*;
导入java.lang.Comparable;
/**
* @desc 比较器,用于“比较器”和“可比较”。
* (01)“可比”
* 它是一个排序接口,仅包含一个函数compareTo()。
* 类实现了Comparable 接口,表示“该类本身支持排序”,可以直接通过Arrays.sort() 或
Collections.sort() 进行排序。
* (02)“比较器”
* 是一个比较器接口,包括两个函数:compare()和equals()。
* 如果一个类实现了Comparator 接口,那么它就是一个“比较器”。其他类可以根据这个比较器进行排序。
* 总结一下:Comparable是内部比较器,Comparator是外部比较器。
* 类本身实现了Comparable比较器,也就是说它本身支持排序;如果它本身没有实现Comparable,它也可以使用外部比较
用于排序的比较器。
*/
公共类CompareComparatorAndComparableTest{
公共静态无效主(字符串[] args){
//创建一个新的ArrayList(动态数组)
ArrayList列表=新的ArrayList();
//将对象添加到ArrayList中
list.add(new Person("ccc", 20));
list.add(new Person("AAA", 30));
list.add(new Person("bbb", 10));
list.add(new Person("ddd", 40));
//打印列表的原始序列
System.out.printf("原排序,list:%sn", list);
//对列表进行排序,这里会按照“Person实现的Comparable接口”排序,即按照“姓名”排序
Collections.sort(列表);
System.out.printf("名称排序,list:%sn", list);
//通过“Comparator (AscAgeComparator)”对列表进行排序
//AscAgeComparator的排序方法为:按照“年龄”升序排序
Collections.sort(列表, new AscAgeComparator());
System.out.printf("Asc(年龄)排序, list:%sn", list);
//通过“Comparator (DescAgeComparator)”对列表进行排序
//DescAgeComparator的排序方法为:按照“年龄”降序排序
Collections.sort(列表, new DescAgeComparator());
System.out.printf("Desc(年龄)排序, list:%sn", list);
//判断两个人是否相等
测试等于();
}
/**
* @desc 测试两个Person 比较是否相等。
* 由于Person实现了equals()函数:如果两个人的年龄和姓名相等,则认为两个人是平等的。
* 所以,这里的p1和p2是相等的。
* TODO: 如果去掉Person 中的equals() 函数,p1 不等于p2
*/
私有静态无效testEquals(){
人p1=new Person("eee", 100);
人p2=new Person("eee", 100);
if (p1.equals(p2)) {
System.out.printf("%s 等于%sn", p1, p2);
} 别的{
System.out.printf("%s 不等于%sn", p1, p2);
}
}
/** * @desc Person 类。 * Person实现了Comparable接口,也就是说Person本身就支持排序*/
私有静态类Person 实现Comparable{
年龄;
字符串名称;
公共人(字符串名称,整数年龄){
this.name=名称;
this.age=年龄;
}
公共字符串getName() {
返回名称;
}
公共int getAge() {
返回年龄;
}
公共字符串toString() {
返回姓名+"-"+年龄;
}
/** * 比较两个人是否相等:如果他们的名字和年龄相等,则认为他们相等*/
布尔等于(人){
if (this.age==person.age this.name==person.name)
返回真;
返回假;
}
/** * @desc 实现“Comparable”接口,即重写compareTo函数。
* 这是通过“人名”进行比较
*/
@覆盖
公共int 比较(人){
return name.compareTo(person.name);
//返回this.name - person.name;
}
}
/** * @desc AscAgeComparator 比较器*
它是“人的年龄的升序比较器”*/
私有静态类AscAgeComparator 实现Comparator{
@覆盖
公共int 比较(人p1,人p2){
返回p1.getAge() - p2.getAge();
}
}
/** * @desc DescAgeComparator 比较器*
它是“人的年龄的升序比较器”*/
私有静态类DescAgeComparator 实现Comparator{
@覆盖
公共int 比较(人p1,人p2){
返回p2.getAge() - p1.getAge();
}
}
}
下面解释该过程。
a) 人员类别定义。如下:
私有静态类Person 实现Comparable{
年龄;字符串名称;
/** * @desc 实现“Comparable”接口,即重写compareTo函数。
* 这是通过“人名”进行比较的*/
@覆盖
公共int 比较(人){
return name.compareTo(person.name);
//返回this.name - person.name;
}
}说明: (01) Person 类代表一个人。 Person 类中有两个属性:年龄和姓名。
(02)Person类实现了Comparable接口,因此可以排序。
b) 在main()中,我们创建一个Person的List数组(列表)。
如下: //New ArrayList(动态数组) ArrayListlist=new ArrayList();
//向ArrayList中添加对象list.add(new Person("ccc", 20));
list.add(new Person("AAA", 30));list.add(new Person("bbb", 10));
list.add(new Person("ddd", 40));c)
接下来,我们打印出列表的所有元素。如下:
//打印列表的原始序列System.out.printf("Original sort, list:%sn", list);d) 然后,我们通过Collections的sort()函数对列表进行排序。由于Person实现了Comparable接口,因此在通过sort()排序时,会按照Person支持的排序方法,即compareTo(Person person)定义的规则进行排序。如下: //对列表进行排序//这里会按照“Person实现的Comparable接口”进行排序,即按照“姓名”进行排序
Collections.sort(列表);
System.out.printf("名称排序,list:%sn", list);e)
比较Comparable和Comparator,我们定义了两个比较器AscAgeComparator和DescAgeComparator,分别对Person进行升序和降序排序。
e.1) AscAgeComparator 根据年龄对Person进行升序排序。代码如下:
/** * @desc AscAgeComparator 比较器* 它是“人的年龄的升序比较器” */
私有静态类AscAgeComparator 实现Comparator{
@覆盖
公共int 比较(人p1,人p2){
返回p1.getAge() - p2.getAge();
}}
e.2) DescAgeComparator Comparator 根据年龄对Person进行降序排序。代码如下: /** *
@desc DescAgeComparator 比较器*
它是“人的年龄的升序比较器”*/
私有静态类DescAgeComparator 实现Comparator{
@覆盖
公共int 比较(人p1,人p2){
返回p2.getAge() - p1.getAge();
}
【Java对象自定义排序技巧与实现方法】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
哇,学了Java很久了,我才知道可以自己定义排序方式!真厉害啊!
有16位网友表示赞同!
终于明白为什么教材里总说要掌握自定义排序规则的重要性啦,原来有这么大用处!
有16位网友表示赞同!
看样子这个定制排序功能可以用在很多场景来优化程序排序的效果吧
有10位网友表示赞同!
之前总是觉得Java的默认排序方法不够灵活,现在看到这篇文章感觉豁然开朗了。
有8位网友表示赞同!
我记得以前读过关于Comparable接口的文章,没想到它在这里发挥这么关键的作用啊!
有6位网友表示赞同!
看来学习Java还得不断更新知识点,这种定制化排序功能非常实用!
有11位网友表示赞同!
这个文章写的真清晰易懂,即使是新手也能理解自定义排序的操作步骤!
有9位网友表示赞同!
分享一下你们自己遇到过哪些需要自定义排序的场景?
有17位网友表示赞同!
感觉掌握了这个技术之后,编程能力提升好多!真的要趁早学习!
有12位网友表示赞同!
自定义排序还能优化程序的运行效率吗?我很想知道具体的实现方法!
有9位网友表示赞同!
这篇教程让我对Java的定制化功能有了更深入的了解!
有9位网友表示赞同!
在实际开发中,这篇文章内容很有帮助!真是一份宝藏级别的学习资源!
有19位网友表示赞同!
原来自定义排序可以用到了 Comparator 接口里,这个信息太实用啦!
有16位网友表示赞同!
我想试试用自定义排序来处理一些复杂的数据结构,看看效果怎么样?
有14位网友表示赞同!
这篇文章让我更加了解Java的深度和强大之处!
有11位网友表示赞同!
感谢作者分享这么实用的知识点,帮助我学习编程道路上进步!
有15位网友表示赞同!
以后遇到需要自定义排序的情况了,就直接参考这篇教程做操作啦!
有18位网友表示赞同!
希望以后还能看到作者分享更多的Java知识,我一直都很想深入学习JAVA!
有12位网友表示赞同!