在业务逻辑中,我们经常需要对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. 数据结构-->栈

    首先,栈是什么? 在代码当中,栈主要是一种实现特殊功能的一种数据结构,而不是像数组.集合之类的数据存储工具.它最大的特点就是后进先出. 那么后进先出是什么? 假设有一个数组,我们向里面添加一个数据,再 ...

  2. 诡异错误二:TypeError: data type not understood

    如何使用Python产生一个数组,数组的长度为1024,数组的元素全为0? 很简单啊, 使用zeros(1024) 即可实现! 如何产生一个2×1024的全0矩阵呢?是否是zeros(2,1024) ...

  3. python——字符串 & 正则表达

    raw字符串(原始字符串) 所见即所得,例如r''My's\n'' Python转义字符 在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符.如下表: 转义字符 描述 \(在行尾时) 续 ...

  4. 设计模式之桥接模式(Bridge模式)

    我想大家小时候都有用蜡笔画画的经历吧.红红绿绿的蜡笔一大盒,根据想象描绘出格式图样.而毛笔下的国画更是工笔写意,各展风采.而今天我们的故事从蜡笔与毛笔说起. 设想要绘制一幅图画,蓝天.白云.绿树.小鸟 ...

  5. 免费的Lucene 原理与代码分析完整版下载

    Lucene是一个基于Java的高效的全文检索库.那么什么是全文检索,为什么需要全文检索?目前人们生活中出现的数据总的来说分为两类:结构化数据和非结构化数据.很容易理解,结构化数据是有固定格式和结构的 ...

  6. 10分钟学会在windows/Linux下设置ASP.Net Core开发环境并部署应用

    创建和开发ASP.NET Core应用可以有二种方式:最简单的方式是通过Visual Studio 2017 来创建,其优点是简单方便,但需要安装最新版本Visual Studio 2017 prev ...

  7. 使用webpack-dev-middleware 和 webpack-hot-middleware 配置一个dev-server

    关于Webpack的资料教程网上已经数不胜数,但是对手动配置一个Express server的确不多,于是我对此进行着重的了解一番. webpack-dev-middleware和webpack-ho ...

  8. xamarin.android 绑定百度地图SDK遇到的问题

    在 xamarin.android 绑定项目中,绑定 百度地图的LBS地图SDK,参考 https://developer.xamarin.com/guides/android/advanced_to ...

  9. cacti监控系统

    cacti 1. cacti安装 IP: 172.25.44.1 环境: Red Hat 6.5 镜像: rhel-server-6.5-x86_64-dvd.iso 火墙: /etc/init.d/ ...

  10. Java基础---继承、抽象、接口

    一.概述         继承是面向对象的一个重要特征.当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可.这时,多个类可以称为子类,单 ...