黑马程序员技术交流社区

标题: Comparable Comparator如何使用 [打印本页]

作者: 黑马振鹏    时间: 2012-7-11 15:39
标题: Comparable Comparator如何使用
比较的时候对于Comparable和Comparator如何使用感觉有点乱,拿捏不准到底该如何使用,有没有大侠举例说明?
作者: 王双宝    时间: 2012-7-11 15:48
学生类:
public class  Student implements Comparator<Student> {
       
        private String name;
        private int age;
        private int score;
       
        public Student(){
               
        }
       
       
       
        public Student(String name,int age,int score){
                setName(name);
                setAge(age);
                setScore(score);
        }
       
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }
        public int getAge() {
                return age;
        }
        public void setAge(int age) {
                this.age = age;
        }
        public int getScore() {
                return score;
        }
        public void setScore(int score) {
                this.score = score;
        }
         
        @Override
        public int compare(Student o1, Student o2) {
                // TODO Auto-generated method stub
                if(o1.getScore()>o2.getScore()){
                        return 1;
                }
                else if(o1.getScore()==o2.getScore()){
                        return 0;
                }
                else{
                        return -1;
                }
               
        }
       
        @Override
        public String toString() {
                // TODO Auto-generated method stub
                return "name: "+this.name+" age: "+this.age+" score: "+this.score;
        }
       

}
客户端类:
public class Client {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Student[] students=new Student[5];
                students[0]=new Student("wangwu",22,78);
                students[1]=new Student("zhangsan",19,45);
                students[2]=new Student("lisi",25,76);
                students[3]=new Student("tianqi",18,98);
                students[4]=new Student("sunba",20,98);
                for(int i=0;i<students.length;i++){
                        System.out.println(students[i]);
                }
               
                System.out.println("--------------------------------------------------------");
                Arrays.sort(students,new Student());//对数组中Student对象按score进行排序.
               
                for(int i=0;i<students.length;i++){
                        System.out.println(students[i]);
                }
        }

}
作者: 刘煜    时间: 2012-7-11 18:02
本帖最后由 刘煜 于 2012-7-11 18:10 编辑

首先你必须清楚Comparator和Comparable两个接口表面是用来比较用的,根本上是为了使集合通过比较能实现排序。当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。下面针对两个接口分别介绍以及在Set集合中的应用:
一、Comparator
强行对某个集合collection对象进行整体排序,可以将Comparator传递给Collections.sort或Arrays.sort。
接口方法: int compare(Object o1, Object o2);
案例:
import java.util.*;
public class SampleComparator implements Comparator<String>
{
public int compare(String o1, String o2)
{
  return toInt(o1) - toInt(o2);
}
//将字符转换成对应的整数
private int toInt(String str)
{
   str = str.replaceAll("一", "1");
   str = str.replaceAll("二", "2");
   str = str.replaceAll("三", "3");
   return Integer.parseInt(str);
}
   
  public static void main(String[] args)
  {
    String[] array = new String[] { "一二", "三", "二" };
    Arrays.sort(array, new SampleComparator()); //按从小到大排序
    for (int i = 0; i < array.length; i++)
    {
      System.out.println(array);
    }
  }
}
结果:
一二
二、Comparable
强行对集合中实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序
接口方法:int compareTo(Object o);
假设对象User,需要按年龄排序:
import java.util.Arrays;
public class User implements Comparable<User>
{
  private String id;
  private int age;
  public User(String id, int age)
  {
    this.id = id;
    this.age = age;
  }
  public int getAge()
  {
    return age;
  }
  public void setAge(int age)
  {
    this.age = age;
  }
  public String getId()
  {
    return id;
  }
  public void setId(String id)
  {
    this.id = id;
  }
  public int compareTo(User u)
  {
    return this.age - u.getAge();
  }
   
  public static void main(String[] args)
  {
    User[] users = new User[] { new User("a", 30), new User("b", 20) };
    Arrays.sort(users);
    for (int i = 0; i < users.length; i++) {
      User user = users;
    System.out.println(user.getId() + " " + user.getAge());
    }
  }
}
三、Comparator和Comparable的区别
1)先看一下使用Comparator对User集合实现排序的方式:一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
       1、类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
       2、可以使用多种排序标准,比如升序、降序等
2)comparable是支持自比较,在集合内部定义的方法实现的排序,而Comparator是支持外部比较,是在集合外部实现的排序。 所以,如想实现排序,就需要在集合外定义Comparator接口的方法compare()或在集合内实现Comparable接口的方法compareTo()。
注意:在TreeSet和TreeMap中添加的自定义对象必须实现Comparable接口
四、Set集合的排序
集合框架中Set集合体系最重要的特点就是可以排序,有两种排序方式,分别用到了Comparable和Comparator
第一种排序方式就是集合的元素对象具备比较性,
此时就需要实现具有比较性的接口Compareble接口的compareTo方法,下面是一个完整的例子:
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
  TreeSet ts = new TreeSet();
  ts.add(new Student("zhangsan",22));
  ts.add(new Student("lisi",28));
  ts.add(new Student("wangwu",21));
  ts.add(new Student("liu",25));

  Iterator  it = ts.iterator();
  while(it.hasNext())
  {
   Student s = (Student)it.next();
   System.out.println(s.getName()+"·····"+s.getAge());
  }
}
public static void sop(Object obj)
{
  System.out.println(obj);
}
}class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
  this.name = name;
  this.age = age;
}

public String getName()
{
  return name;
}
public int getAge()
{
  return age;
}
public int compareTo(Object obj)
{
   if(!(obj instanceof Student))
   throw new RuntimeException("不是学生对象");
  Student s = (Student)obj;
  System.out.println(this.name+"··Compare··"+s.name);
  if(this.age>s.age)
   return 1;
  if(this.age==s.age)
  {
   return this.name.compareTo(s.name); //年龄相同时,比较姓名。
  }
  return -1;
}
}
第二种排序方式就是
让集合自身具备比较性,在集合初始化时就有了比较方式,这时需要定义比较器(实现Comparator接口,覆盖compare方法,区别Comparable接口和CompareTo方法),将比较器对象作为参数传递给TreeSet集合的构造函数。这种方式适合元素本身不具备比较性或者排序方式与元素本身的排序方式不一致的情况。完整的例子如下:
import java.util.*;
class TreeSetDemo2
{
public static void main(String[] args)
{
  TreeSet ts = new TreeSet(new MyCompare());
  
  ts.add(new Student("zhangsan",22));
  ts.add(new Student("lisi",28));
  ts.add(new Student("lisi",30));
  ts.add(new Student("wangwu",21));
  ts.add(new Student("liu",25));
  ts.add(new Student("zhao",25));
  
  Iterator  it = ts.iterator();
  while(it.hasNext())
  {
   Student s = (Student)it.next();
   System.out.println(s.getName()+"·····"+s.getAge());
  }
}
}

class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
  Student s1 = (Student)o1;
  Student s2 = (Student)o2;
  
  int result = s1.getName().compareTo(s2.getName());
  if(result==0)//姓名相同时,比较年龄
  {
   return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
  }
  return result;
}
}
希望以上的例子对你有帮助!!!

作者: 包晗    时间: 2012-7-11 18:22
一、Comparator

强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sort或Arrays.sort。

接口方法:


  /**
   * @return o1小于、等于或大于o2,分别返回负整数、零或正整数。
   */
  int compare(Object o1, Object o2);

案例:

import java.util.Arrays;
import java.util.Comparator;

public class SampleComparator implements Comparator {

  public int compare(Object o1, Object o2) {
    return toInt(o1) - toInt(o2);
  }

  private int toInt(Object o) {
    String str = (String) o;
    str = str.replaceAll("一", "1");
    str = str.replaceAll("二", "2");
    str = str.replaceAll("三", "3");
    //
    return Integer.parseInt(str);
  }

  /**
   * 测试方法
   */
  public static void main(String[] args) {
    String[] array = new String[] { "一二", "三", "二" };
    Arrays.sort(array, new SampleComparator());
    for (int i = 0; i < array.length; i++) {
      System.out.println(array[i]);
    }
  }

}
二、Comparable

强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。

接口方法:


  /**
   * @return 该对象小于、等于或大于指定对象o,分别返回负整数、零或正整数。
   */
  int compareTo(Object o);
import java.util.Arrays;

public class User implements Comparable {

  private String id;
  private int age;

  public User(String id, int age) {
    this.id = id;
    this.age = age;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public int compareTo(Object o) {
    return this.age - ((User) o).getAge();
  }

  /**
   * 测试方法
   */
  public static void main(String[] args) {
    User[] users = new User[] { new User("a", 30), new User("b", 20) };
    Arrays.sort(users);
    for (int i = 0; i < users.length; i++) {
      User user = users[i];
      System.out.println(user.getId() + " " + user.getAge());
    }
  }

}

三、Comparator和Comparable的区别

先看一下使用Comparator对User集合实现排序的方式:

import java.util.Arrays;
import java.util.Comparator;

public class UserComparator implements Comparator {

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

  /**
   * 测试方法
   */
  public static void main(String[] args) {
    User[] users = new User[] { new User("a", 30), new User("b", 20) };
    Arrays.sort(users, new UserComparator());
    for (int i = 0; i < users.length; i++) {
      User user = users[i];
      System.out.println(user.getId() + " " + user.getAge());
    }
  }

}

百度帮你搜的...我从这个例子里获得不少理解...希望对你有帮助
作者: 黑马振鹏    时间: 2012-7-11 19:04
王双宝 发表于 2012-7-11 15:48
学生类:
public class  Student implements Comparator {
       

兄弟 第二个例子啥意思?
作者: 王双宝    时间: 2012-7-11 19:11
啸傲江湖007 发表于 2012-7-11 19:04
兄弟 第二个例子啥意思?

Client是用来测试Student类功能的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2