Java中如何给一个对象排序

=====http://www.qqread.com/java/2010/04/w493015.html=====

 

当我们排序的对象不止是简单的数据类型的时候

  我们可以通过 实现Comparable 和Comparator 接口来完整对对象的排序

  Comparable和Compartor 的区别?

  Comparable 是一个自身已经支持自比较的(如String ,Integer) 的接口

  Comparator 可以说是一个 专用的比较器 当对象本身 不支持自排序和自比较函数的时候

  我们可以通过实现Compartor 来比较两对象的大小

  Comparable 是一个比较通用的接口 用户可以通过他实现 排序功能

  而 Comparator 可以看作一种算法 一种设计模式 (可以看作是一个策略模式 就是不改变对象自身,而用一个策略对象改变对象行为)

  Comparable 相对比较固定 与具体类绑定 ,

  Comparator 比较灵活 可以与任何需要实现功能的类 绑定

  Comparable 可以说是 静态绑定

  Comparator 可以说是动态绑定

  Comparable

  此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareTo 方法被称为它的自然比较方法。

  实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。

  对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与 e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致。注意,null 不是任何类的实例,即使 e.equals(null) 返回 false,e.compareTo(null) 也会抛出 NullPointerException。

  强烈推荐(虽然不是必需的)使自然排序与 equals 一致。这是因为在使用其自然排序与 equals 不一致的元素(或键)时,没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。

  而 Comparator

  比较函数强行对某些对象 collection 进行整体排序。可以将 Comparator 传递给 sort 方法(如 Collections.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如 TreeSet 或 TreeMap)的顺序。

  当且仅当对于一组元素 S 中的每个 e1 和 e2 而言,(compare((Object)e1, (Object)e2)==0) 与 e1.equals((Object)e2) 具有相等的布尔值时,Comparator c 强行对 S 进行的排序才叫做与等号一致 的排序。

  当使用具有与等号一致的强行排序能力的 comparator 对有序 set(或有序映射)进行排序时,应该小心谨慎。假定一个带有显式 Comparator c 的有序 set(或有序映射)与从 set S 中抽取出来的元素(或键)一起使用。如果 c 强行对 S 进行的排序与等号一致,那么有序 set(或有序映射)将是行为“怪异的”。尤其是那些将违背根据 equals 所定义 set(或映射)的常规协定的有序 set(或有序映射)。

 

 

 

http://accpxudajian.iteye.com/blog/919361        

java实现按照自定义对象的某个属性排序

package com;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Sort {
 public Sort() { }
 public static void main(String[] args) {
  List<User> list = new ArrayList<User> ();
  User u1 = new User("a",21,0);
  User u2 = new User("b",21,2);
  User u3 = new User("c",21,4);
  User u4 = new User("d",21,1);
  User u5 = new User("e",21,3);
  list.add(u1);
  list.add(u2);
  list.add(u3);
  list.add(u4);
  list.add(u5);
  int len = list.size();
  System.out.println("排序前:");
  for(int i=0;i<len;i++){
   User u = list.get(i);
   System.out.print(u.getOrder()+" ");
  }
  //Collections.sort(list,new UserCompator());   //Collections类的的静态sort方法,传递一个compator对象
  Collections.sort(list);
  //实现倒叙
  System.out.println("/n排序后:");
  for(int i=0;i<len;i++){
   User u = list.get(i);
   System.out.print(u.getOrder()+" ");
  }
  //实现倒叙
  Collections.reverse(list);//Collections类的静态reverse方法
  System.out.println("/n倒叙后:");
  for(int i=0;i<len;i++){
   User u = list.get(i);
   System.out.print(u.getOrder()+" ");
  }
 }
}

 

//模拟用户类
//J2EE项目的bean最好都实现可序列化
/*序列化得作用:什么叫序列化?通俗点...就是对你的对象添加一个序列号作为标识(对应内存中相对应的对象),然后流化,
当反序列化的时候,把该对象恢复到内存,如果该对象的序列号和内存中的对象相对应,则恢复到内存中的对象,
否则的化,直接创建一个对象到内存

 * */
class User implements Serializable, Comparable<User>{   // Comparable<User>规定,当前的compate方法的参数必须是User
 private static final long serialVersionUID = 2802777044952669007L;
 private String Name;
 private int Age;
 private int Order;//排序的属性
 
 public User(){}; //无参构造
 //构造
 public User(String name,int age,int order){
  this.Name = name;
  this.Age = age;
  this.Order = order;
 }
 
 public int getOrder() {
  return Order;
 }
 public void setOrder(int order) {
  Order = order;
 }
 public String getName() {
  return Name;
 }
 public void setName(String name) {
  Name = name;
 }
 public int getAge() {
  return Age;
 }
 public void setAge(int age) {
  Age = age;
 }
 //必须重写的方法,而且参数必须是User,声明类的时候已经规定。
    public int compareTo(User u ) {
       return this.Order-u.getOrder();
    }  
}
//自定义的compator类,在Collections排序的时候使用(也可以不使用用)
class UserCompator implements Comparator<User>{

 public int compare(User o1, User o2) {
  return o1.getOrder()-o2.getOrder();
 }
}


结果:

排序前:
0 2 4 1 3
排序后:
0 1 2 3 4
倒叙后:
4 3 2 1 0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值