在业务逻辑中,我们经常需要对list进行排序,就像下面这样:

Collections.sort(l);

如果l中的元素是String类型,你会发现sort方法将使用字母顺序排序。如果l中的元素是Date类型,sort方法将使用日历顺序排序。这是因为String和Date都实现了Comparable接口,也就是说,如果你想对某种对象进行排序,那么它必须实现Comparable接口。在Java语言中,实现该接口的类罗列如下:

Classes Implementing Comparable
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-对象排序的更多相关文章

  1. Java对象排序

    java实现对象比较,可以实现java.lang.Comparable或java.util.Comparator接口 //Product.java import java.util.Date; //p ...

  2. Java 对象排序详解

    很难想象有Java开发人员不曾使用过Collection框架.在Collection框架中,主要使用的类是来自List接口中的ArrayList,以及来自Set接口的HashSet.TreeSet,我 ...

  3. java对象排序(Comparable)详细实例

    对象实现Comparable接口 public class Field implements Comparable<Field>{ private String name; private ...

  4. [Java] 对象排序示例

    package test.collections; import java.util.ArrayList; import java.util.Collection; import java.util. ...

  5. Java对象排序两种方法

    转载:https://blog.csdn.net/wangtaocsdn/article/details/71500500 有时候需要对对象列表或数组进行排序,下面提供两种简单方式: 方法一:将要排序 ...

  6. 多字段 java对象排序

    public class ReflexUtil { static Logger logger = LoggerFactory.getLogger(ReflexUtil.class); //getMet ...

  7. Java笔记12:Java对象排序

    代码: import java.util.Arrays; import java.util.Comparator; class Person { private String name; privat ...

  8. Java - 简单的对象排序 - Comparator

    注:对象排序,就是对对象中的某一字段进行比较,以正序或倒序进行排序. 例: 需要排序的对象: public class Person { public int age; public String n ...

  9. [个人原创]关于java中对象排序的一些探讨(三)

    这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...

  10. Java集合中对象排序

    集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...

随机推荐

  1. Docker 学习笔记

    1. Docker 资源 英文资源 Docker 官网:https://www.docker.com/ Docker 官方文档:https://docs.docker.com/ Docker wind ...

  2. sqlte3 的基本使用4

    sqlite 的order by 语句是用来对数据进行升序降序排序的,asc 是升序,des 是降序 sqlite> select * from student; id name age --- ...

  3. session和cookie的辨析[阅读]

    session和cookie是网站浏览中较为常见的两个概念,也是比较难以辨析的两个概念,但它们在点击流及基于用户浏览行为的网站分析中却相当关键.基于网上一些文章和资料的参阅,及作者个人的应用体会,对这 ...

  4. 【LeetCode】数组-4(581)-给未排序数组中子数组排序使得整个数组排序 找到这个最小的子数组

    这道题目感觉并不太容易,也并没有想到什么比较好的方法,看来还是积累太少. 思路一:两个指针向后遍历,分别记下造成逆序的最小和最大下标位置 优化的暴力解法(很精妙,面试的时候可以说出来) 思想:两个指针 ...

  5. C++ Socket学习记录 -3

    WinSocket套接字之间的数据传输 在客户端和服务端建立链接后,接着就是在套接字之间传输数据. 很简单的使用 recv 接收数据,用send发送数据,单但是出现一个问题,不管接收还是发送,数据都是 ...

  6. Vue动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  7. STL sort函数的用法

    sort在STL库中是排序函数,有时冒泡.选择等O(N^2)算法会超时时,我们可以使用STL中的快速排序O(N log N)完成排序 sort在<algorithm>库里面,原型如下: t ...

  8. struts2的java.lang.NoSuchMethodException异常处理(转)

    不久前在学习struts时出现这个错误,在网上搜索了半天,发现答案不一.将其总结如下,以方便大家参考. 1. 你有没有试试看 其它的方法能不能用,要是都是这种情况的话,可能是你的Action类没有继承 ...

  9. shell 编程案例整理

    一.统计成绩文件 [zheng@localhost ~]$ cat score.txt ngsan lisi 81.5 wangwu zhangsan lisi wangwu zhangsan lis ...

  10. 在 ASP.NET Core 中执行租户服务

    在 ASP.NET Core 中执行租户服务 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunna ...