在业务逻辑中,我们经常需要对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. 菜鸟装逼指南--linux内核中听过就能记住的概念

    打算给我们部门弄个内部分享.发现大家对一些底层知识的认知停留在一句一句的,比如听说JVM使用-XX:-UseBiasedLocking取消偏向锁可以提高性能,因为它只适用于非多线程高并发应用.使用数字 ...

  2. include包含头文件的语句中,双引号和尖括号的区别

    include包含头文件的语句中,双引号和尖括号的区别   #include <>格式:引用标准库头文件,编译器从标准库目录开始搜索 #incluce ""格式:引用非 ...

  3. OpenCV探索之路(二十四)图像拼接和图像融合技术

    图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...

  4. Orleans—一些概念

    Orleans-一些概念 这是Orleans系列文章中的一篇.首篇文章在此 这个文章聊一聊Orleans的概念.以下文章大部分翻译自官方教程,还有一些结合实际的应用经验,并对以前文章留下的坑进行填平. ...

  5. Clang之语法抽象语法树AST

    语法分析器的任务是确定某个单词流是否能够与源语言的语法适配,即设定一个称之为上下文无关语言(context-free language)的语言集合,语法分析器建立一颗与(词法分析出的)输入单词流对应的 ...

  6. quartz学习笔记(一)简单入门

    前言 quartz是Java编写的一款开源的任务调度开发框架,在项目开发中很多场景都可以用到,比如订单超期自动收货. 所谓程序源于生活,生活中也有很多场景可以用quartz来模拟,比如工作日早上七点起 ...

  7. 【Zookeeper】3.4.9 基本配置

    [hadoop@master1 ~]$ cat zookeeper/conf/zoo.cfg # The number of milliseconds of each tick 每个心跳的时长 单位为 ...

  8. python之路第二天 随便记记 今天主要很郁闷

    为何要有操作系统 为了让程序员更轻松的完成命令电脑工作而存在的,控制硬件,服务于软件. 操作系统的位置 操作系统位于软件和硬件之间.操作系统由内核(运行于内核态,控制硬件)和系统调用(运行于用户态,为 ...

  9. 学问Chat UI(3)

    前言 上文学问Chat UI(2)分析了消息适配器的实现; 本文主要学习下插件功能如何实现的.并以图片插件功能作为例子详细说明,分析从具体代码入手; 概要 分析策略说明 "+"功能 ...

  10. Struts2使用小问题-NoSuchFieldException

    五月 12, 2017 4:55:14 下午 com.opensymphony.xwork2.util.logging.jdk.JdkLogger warn 警告: couldn't clear to ...