Java-对象排序
在业务逻辑中,我们经常需要对list进行排序,就像下面这样:
Collections.sort(l);
如果l中的元素是String类型,你会发现sort方法将使用字母顺序排序。如果l中的元素是Date类型,sort方法将使用日历顺序排序。这是因为String和Date都实现了Comparable接口,也就是说,如果你想对某种对象进行排序,那么它必须实现Comparable接口。在Java语言中,实现该接口的类罗列如下:
| Class | Natural Ordering |
|---|---|
Byte |
Signed numerical |
Character |
Unsigned numerical |
Long |
Signed numerical |
Integer |
Signed numerical |
Short |
Signed numerical |
Double |
Signed numerical |
Float |
Signed numerical |
BigInteger |
Signed numerical |
BigDecimal |
Signed numerical |
Boolean |
Boolean.FALSE < Boolean.TRUE |
File |
System-dependent lexicographic on path name |
String |
Lexicographic |
Date |
Chronological |
CollationKey |
Locale-specific lexicographic |
如果某个类是别人写的,它确实没有实现该接口,那就对排序问题无能为力了么?不是的,sort还有另一种形式:
Collections.sort(list, comparator)
只有这两种方法。如果以上两种方法你都没有做,那么sort方法将抛出异常。
Comparable接口
Comparable接口形式如下:
public interface Comparable<T> {
public int compareTo(T o);
}
是的,它只有一个方法。你必须在该方法中定义对象是如何比较的。下面是一个demo:
SortDemo.java
package Colloections; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class SortDemo { public static void main(String[] args) {
// TODO Auto-generated method stub
new SortDemo().sort();
} private void sort(){
Person p1 = new Person("bob", 5);
Person p2 = new Person("albert", 8);
Person p3 = new Person("bob", 13); List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
System.out.printf("排序前:%n");
for (Person person : list) {
System.out.printf(person.toString());
} Collections.sort(list);
System.out.printf("排序后:%n");
for (Person person : list) {
System.out.printf(person.toString());
}
}
} class Person implements Comparable<Person>{ public String name;
public int age; public Person(String n, int a){
name = n;
age = a;
} public String toString() {
return String.format("Name is %s, Age is %d%n", name, age);
} @Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
//排序优先级为:姓名/年龄
int nameComp = this.name.compareTo(o.name);
return (nameComp != 0 ? nameComp : (this.age - o.age));
}
}
程序输出如下:
排序前:
Name is bob, Age is 5
Name is albert, Age is 8
Name is bob, Age is 13
排序后:
Name is albert, Age is 8
Name is bob, Age is 5
Name is bob, Age is 13
Comparator
Comparator接口提供一个独立的排序功能,这有两个用处:1.你不想使用某个类自带的compareTo逻辑进行排序;2.某个类并没有继承Comparable接口。可见,Comparator接口使得排序更加灵活。它的形式如下所示:
public interface Comparator<T> {
int compare(T o1, T o2);
}
是的,一个方法就够了。当o1比o2小于,等于,大于时,compare方法将返回一个负数,零或者正数。使用demo如下:
SortDemo.java
package Colloections; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class SortDemo { public static void main(String[] args) {
// TODO Auto-generated method stub
//new SortDemo().sort();
new SortDemo().sortByComparatpr();
} private void sortByComparatpr(){
Person p1 = new Person("bob", 5);
Person p2 = new Person("albert", 8);
Person p3 = new Person("bob", 13); List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
System.out.printf("排序前:%n");
for (Person person : list) {
System.out.printf(person.toString());
} PersonComparator comparator = new PersonComparator();
Collections.sort(list, comparator);
System.out.printf("排序后:%n");
for (Person person : list) {
System.out.printf(person.toString());
}
} private void sort(){
Person p1 = new Person("bob", 5);
Person p2 = new Person("albert", 8);
Person p3 = new Person("bob", 13); List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
System.out.printf("排序前:%n");
for (Person person : list) {
System.out.printf(person.toString());
} Collections.sort(list);
System.out.printf("排序后:%n");
for (Person person : list) {
System.out.printf(person.toString());
}
}
} class Person implements Comparable<Person>{ public String name;
public int age; public Person(String n, int a){
name = n;
age = a;
} public String toString() {
return String.format("Name is %s, Age is %d%n", name, age);
} @Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
//排序优先级为:姓名/年龄
int nameComp = this.name.compareTo(o.name);
return (nameComp != 0 ? nameComp : (this.age - o.age));
}
} class PersonComparator implements Comparator<Person>{ @Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub return o2.compareTo(o1);
}
}
程序输出如下:
排序前:
Name is bob, Age is 5
Name is albert, Age is 8
Name is bob, Age is 13
排序后:
Name is bob, Age is 13
Name is bob, Age is 5
Name is albert, Age is 8
注意,这里的输出是降序排列的,因为在compare方法中使用o2与o1进行了比较。如果需要升序排列,则如下修改即可:
return o1.compareTo(o2);
注意,不要这样修改:
return -o2.compareTo(o1);
这是因为compareTo返回的负数值是不确定的,而有一个特殊的负整数,取负时结果仍为负数:
-Integer.MIN_VALUE == Integer.MIN_VALUE
Java-对象排序的更多相关文章
- Java对象排序
java实现对象比较,可以实现java.lang.Comparable或java.util.Comparator接口 //Product.java import java.util.Date; //p ...
- Java 对象排序详解
很难想象有Java开发人员不曾使用过Collection框架.在Collection框架中,主要使用的类是来自List接口中的ArrayList,以及来自Set接口的HashSet.TreeSet,我 ...
- java对象排序(Comparable)详细实例
对象实现Comparable接口 public class Field implements Comparable<Field>{ private String name; private ...
- [Java] 对象排序示例
package test.collections; import java.util.ArrayList; import java.util.Collection; import java.util. ...
- Java对象排序两种方法
转载:https://blog.csdn.net/wangtaocsdn/article/details/71500500 有时候需要对对象列表或数组进行排序,下面提供两种简单方式: 方法一:将要排序 ...
- 多字段 java对象排序
public class ReflexUtil { static Logger logger = LoggerFactory.getLogger(ReflexUtil.class); //getMet ...
- Java笔记12:Java对象排序
代码: import java.util.Arrays; import java.util.Comparator; class Person { private String name; privat ...
- Java - 简单的对象排序 - Comparator
注:对象排序,就是对对象中的某一字段进行比较,以正序或倒序进行排序. 例: 需要排序的对象: public class Person { public int age; public String n ...
- [个人原创]关于java中对象排序的一些探讨(三)
这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...
- Java集合中对象排序
集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...
随机推荐
- 微软认知服务 Luis
学习认知服务 Luis(Language understand intellgence service) 简述: 开发者可以通过Luis开发可以理解人类语言的只能应用,学习人类语言分析语义. 利用这个 ...
- 17个新手常见Python运行时错误
当初学 Python 时,想要弄懂 Python 的错误信息的含义可能有点复杂.这里列出了常见的的一些让你程序 crash 的运行时错误. 1)忘记在 if , elif , else , for , ...
- linux守护进程、SIGHUP与nohup详解
前端时间帮忙定位个问题.docker容器故障恢复后,其中的keepalived进程始终无法启动,也看不到Keepalived的日志. strace 查看系统调用之后,发现了原因所在 socket(PF ...
- 运营商级NAT(Carrier-grade NAT)
运营商级NAT(Carrier-grade NAT) 运营商级(Carrier-grade)NAT,是用于缓解是IPV4地址枯竭的一种方法,通过这种方法,原来被分配公网ip的端点.家庭网络等可以被 ...
- 实现QObject与JavaScript通讯(基于QWebEngine + QWebChannel)
实现QObject与JavaScript通讯(基于QWebEngine + QWebChannel) 通过使用QtWebEngine加载相关页面,然后用QtWebChannel作为Qt与Javascr ...
- Redis环境搭建(MacOS)
Redis是一个开源的key-value类型的存储系统,大部分数据存在于内存中,所有读写速度十分快.其支持的存储value数据类型有多种,如:strings.hashes.lists.sets.sor ...
- 简单的用js打印乘法口诀表
<script type="text/javascript"> //乘法口诀表 for (var i = 1; i < 10; i++) { for (var j ...
- Linux中mysql乱码问题
注意: 关于utf8和gbk的区别详细见:linux中文乱码问题解决办法 http://www.linuxidc.com/Linux/2010-04/25757.htm ,下面的配置中根据自己要求选择 ...
- JS中的运算符 以及变量和输入输出
1.算术运算(单目运算符) + 加 .- 减.* 乘. / 除. % 取余.++ 自增.-- 自减. >>> +:有两种作用,链接字符串/加法运算,当+两边全为数字时,进行加法运算, ...
- JDK环境变量的配置
JDK环境变量的配置.. ==================>>> 右键“我的电脑”,选择“属性”,弹出的对话框中选择“高级系统设置” 在弹出的系统属性对话框中.选择“高级”,再选 ...