Java:比较与排序

1. 两种比较接口分析
集合框架 中有两种比较接口: Comparable 接口和 Comparator 接口。 Comparable 是通用的接口,用户可以实现它来完成自己特定的比较,而 Comparator 可以看成一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成一种设计模式,将算法和数据分离。
前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。
一个类实现了 Camparable 接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用 Sort 方法排序了。
Comparator 的作用有两个:
1 、如果类的设计师没有考虑到 Compare 的问题而没有实现 Comparable 接口,可以通过 Comparator 来实现比较算法进行排序;
2 、为了使用不同的排序标准做准备,比如:升序、降序或其他什么序。
2 Comparable 接口
public interface Comparable<T> {
    public int compareTo(T o);
}
java.lang. Comparable 接口定义类的自然顺序,实现该接口的类就可以按这种方式排序。  
1 int compareTo(Object o): 比较当前实例对象与对象 o ,如果位于对象 o 之前,返回负值,如果两个对象在排序中位置相同,则返回 0 ,如果位于对象 o 后面,则返回正值。
 
2 )在 Java 2 SDK 版本 1.4 中有二十四个类实现 Comparable 接口。下表展示了 8 种基本类型的自然排序。虽然一些类共享同一种自然排序,但只有相互可比的类才能排序。
排序
BigDecimal,BigInteger,Byte,Double, Float,Integer,Long,Short
按数字大小排序
Character
Unicode 值的数字大小排序
String
按字符串中字符 Unicode 值排序
利用 Comparable 接口创建自己的类的排序顺序,只是实现 compareTo() 方法的问题。通常就是依赖几个数据成员的自然排序。同时类也应该覆盖 equals() hashCode() 以确保两个相等的对象返回同一个哈希码。
这个接口的作用:如果数组或者集合中的(类)元素实现了该接口的话 , 我们就可以调用 Collections.sort Arrays.sort 排序,或应用于有序集合 TreeSet TreeMap 中。
下面设计一个有序的类 Person ,它实现 Comparable 接口,以年龄为第一关键字,姓名为第二关键字升序排序。
Person.java
package com.zj.sort.comparable;
 
public class Person implements Comparable<Person> {
    private int age ;
    private String name ;
 
    public Person( int age, String name) {
       this . age = age;
       this . name = name;
    }
 
    public int compareTo(Person person) {
       int cop = age - person.getAge();
       if (cop != 0)
           return cop;
       else
           return name .compareTo(person. name );
    }
 
    public int getAge() {
       return age ;
    }
 
    public String getName() {
       return name ;
    }
 
    public int hashCode() {
       int result = 17;
       result = 37 * result + age ;
       result = 37 * result + name .hashCode();
       return result;
    }
 
    public boolean equals(Object o) {
       if (!(o instanceof Person))
           return false ;
       Person person = (Person) o;
       return ( age == person. age ) && ( name .equals(person. name ));
    }
 
    public String toString() {
       return ( age + "{" + name + "}" );
    }
}
2.1 测试 Arrays.sort ()方法
ArraysSortUnit.java
package com.zj.sort.comparable;
import java.util.Arrays;
import com.zj.compare.Person;
 
public class ArraysSortUnit {
    public static void main(String[] args) {
       Person[] ps = { new Person(20, "Tom" ), new Person(20, "Jeff" ),
              new Person(30, "Mary" ), new Person(20, " Ada " ),
              new Person(40, "Walton" ), new Person(61, "Peter" ),
              new Person(20, "Bush" ) };
       System. out .println(Arrays.toString(ps));
       Arrays.sort(ps);
       System. out .println(Arrays.toString(ps));
    }
}
结果:
[20{Tom}, 20{Jeff}, 30{Mary}, 20{ Ada }, 40{Walton}, 61{Peter}, 20{Bush}]
[20{ Ada }, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary}, 40{Walton}, 61{Peter}]
2.2 测试 Collections.sort ()方法
CollctionsSortUnit.java
package com.zj.sort.comparable;
import java.util.Arrays;
import java.util.Collections;
import com.zj.compare.Person;
 
public class CollctionsSortUnit {
    public static void main(String[] args) {
       Person[] ps = { new Person(20, "Tom" ), new Person(20, "Jeff" ),
              new Person(30, "Mary" ), new Person(20, " Ada " ),
               new Person(40, "Walton" ), new Person(61, "Peter" ),
              new Person(20, "Bush" ) };
       System. out .println(Arrays.toString(ps));
       Collections.sort(Arrays.asList(ps));
       System. out .println(Arrays.toString(ps));
    }
}
结果:
[20{Tom}, 20{Jeff}, 30{Mary}, 20{ Ada }, 40{Walton}, 61{Peter}, 20{Bush}]
[20{ Ada }, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary}, 40{Walton}, 61{Peter}]
2.3 测试 TreeSet
TreeSetUnit.java
package com.zj.sort.comparable;
import java.util.TreeSet;
import com.zj.compare.Person;
 
public class TreeSetUnit {
    public static void main(String[] args) {
       TreeSet<Person> set = new TreeSet<Person>();
       set.add( new Person(20, "Tom" ));
       set.add( new Person(20, "Jeff" ));
       set.add( new Person(30, "Mary" ));
       set.add( new Person(20, " Ada " ));
       set.add( new Person(40, "Walton" ));
       set.add( new Person(61, "Peter" ));
       set.add( new Person(20, "Bush" ));
       System. out .println(set);
    }
}
结果:
[20{ Ada }, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary}, 40{Walton}, 61{Peter}]
2.4 测试 TreeMap
TreeMapUnit.java
package com.zj.sort.comparable;
import java.util.TreeMap;
import com.zj.compare.Person;
 
public class TreeMapUnit {
    public static void main(String[] args) {
       TreeMap<Person, String> map = new TreeMap<Person, String>();
       map.put( new Person(20, "Tom" ), "Tom" );
       map.put( new Person(20, "Jeff" ), "Jeff" );
       map.put( new Person(30, "Mary" ), "Mary" );
       map.put( new Person(20, " Ada " ), " Ada " );
       map.put( new Person(40, "Walton" ), "Walton" );
       map.put( new Person(61, "Peter" ), "Peter" );
       map.put( new Person(20, "Bush" ), "Bush" );
       System. out .println(map);
    }
}
结果:
{20{ Ada }= Ada , 20{Bush}=Bush, 20{Jeff}=Jeff, 20{Tom}=Tom, 30{Mary}=Mary, 40{Walton}=Walton, 61{Peter}=Peter}
3. Comparator 接口
public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}
若一个类不能用于实现 java.lang.Comparable ,或者不喜欢缺省的 Comparable 行为并想提供自己的排序顺序 ( 可能多种排序方式 ) ,你可以实现 Comparator 接口,从而定义一个比较器。
 
1 int compare(Object o1, Object o2): 对两个对象 o1 o2 进行比较,如果 o1 位于 o2 的前面,则返回负值,如果在排序顺序中认为 o1 o2 是相同的,返回 0 ,如果 o1 位于 o2 的后面,则返回正值。
 
2 )与 Comparable 相似, 0 返回值不表示元素相等。一个 0 返回值只是表示两个对象排在同一位置。由 Comparator 用户决定如何处理。
 
3 boolean equals(Object obj): 指示对象 obj 是否和比较器相等。该方法覆写 Object equals() 方法,检查的是 Comparator 实现的等同性,不是处于比较状态下的对象。
下面设计一个定义完整 equals 方法和 hashCode 方法的类 Person
Person.java
package com.zj.sort.comparator;
 
public class Person {
    private String firstName ;
    private String lastName ;
    private int age ;
 
    public Person( int age, String firstName, String lastName) {
       this . age = age;
       this . firstName = firstName;
       this . lastName = lastName;
    }
 
    public int getAge() {
       return age ;
    }
 
    public String getFirstName() {
       return firstName ;
    }
 
    public String getLastName() {
       return lastName ;
    }
 
    public int hashCode() {
       int result = 17;
       result = 37 * result + age ;
       result = 37 * result + firstName .hashCode();
       result = 37 * result + lastName .hashCode();
       return result;
    }
 
    public boolean equals(Object o) {
       if (!(o instanceof Person))
           return false ;
       Person p = (Person) o;
       return ( age == p. age ) && ( firstName .equals(p. firstName ))
              && ( lastName .equals(p. lastName ));
    }
 
    public String toString() {
       return ( age + "{" + firstName + " " + lastName + "}" );
    }
}
下面设计两个比较器。
FirstNameComparator.java
package com.zj.sort.comparator;
import java.util.Comparator;
 
// 实现按 FirstName 优先排序
public class FirstNameComparator implements Comparator<Person> {
    public int compare(Person person, Person anotherPerson) {
       String lastName1 = person.getLastName().toUpperCase();
       String firstName1 = person.getFirstName().toUpperCase();
       String lastName2 = anotherPerson.getLastName().toUpperCase();
       String firstName2 = anotherPerson.getFirstName().toUpperCase();
       if (firstName1.equals(firstName2))
           return lastName1.compareTo(lastName2);
       else
           return firstName1.compareTo(firstName2);
    }
}
LastNameComparator.java
package com.zj.sort.comparator;
import java.util.Comparator;
 
// 实现按 LastName 优先排序
public class LastNameComparator implements Comparator<Person> {
    public int compare(Person person, Person anotherPerson) {
       String lastName1 = person.getLastName().toUpperCase();
       String firstName1 = person.getFirstName().toUpperCase();
       String lastName2 = anotherPerson.getLastName().toUpperCase();
       String firstName2 = anotherPerson.getFirstName().toUpperCase();
       if (lastName1.equals(lastName2))
           return firstName1.compareTo(firstName2);
       else
           return lastName1.compareTo(lastName2);
    }
}
下面通过上述两个比较器,调用 Collections.sort Arrays.sort 排序,以及将其应用于有序集合 TreeSet TreeMap 中。
3.1 测试 Arrays.sort ()方法
ArraysSortUnit.java
package com.zj.sort.comparator;
import java.util.Arrays;
 
public class ArraysSortUnit {
    public static void main(String[] args) {
       Person[] ps = { new Person(20, "Tom" , "A" ),
              new Person(20, "Jeff" , "A" ), new Person(30, "Mary" , "A" ),
              new Person(20, " Ada " , "B" ), new Person(40, "Walton" , "B" ),
              new Person(61, "Peter" , "B" ), new Person(20, "Bush" , "B" ) };
       System. out .println(Arrays.toString(ps));
       Arrays.sort(ps, new FirstNameComparator());
       System. out .println(Arrays.toString(ps));
       Arrays.sort(ps, new LastNameComparator());
       System. out .println(Arrays.toString(ps));
    }
}
结果:
[20{Tom A}, 20{Jeff A}, 30{Mary A}, 20{ Ada B}, 40{Walton B}, 61{Peter B}, 20{Bush B}]
[20{ Ada B}, 20{Bush B}, 20{Jeff A}, 30{Mary A}, 61{Peter B}, 20{Tom A}, 40{Walton B}]
[20{Jeff A}, 30{Mary A}, 20{Tom A}, 20{ Ada B}, 20{Bush B}, 61{Peter B}, 40{Walton B}]
3.2 测试 Collections.sort ()方法
CollctionsSortUnit.java
package com.zj.sort.comparator;
import java.util.Arrays;
import java.util.Collections;
 
public class CollectionsSortUnit {
    public static void main(String[] args) {
       Person[] ps = { new Person(20, "Tom" , "A" ),
              new Person(20, "Jeff" , "A" ), new Person(30, "Mary" , "A" ),
              new Person(20, " Ada " , "B" ), new Person(40, "Walton" , "B" ),
              new Person(61, "Peter" , "B" ), new Person(20, "Bush" , "B" ) };
       System. out .println(Arrays.toString(ps));
       Collections.sort(Arrays.asList(ps), new FirstNameComparator());
       System. out .println(Arrays.toString(ps));
       Collections.sort(Arrays.asList(ps), new LastNameComparator());
       System. out .println(Arrays.toString(ps));
    }
}
结果:
[20{Tom A}, 20{Jeff A}, 30{Mary A}, 20{ Ada B}, 40{Walton B}, 61{Peter B}, 20{Bush B}]
[20{ Ada B}, 20{Bush B}, 20{Jeff A}, 30{Mary A}, 61{Peter B}, 20{Tom A}, 40{Walton B}]
[20{Jeff A}, 30{Mary A}, 20{Tom A}, 20{ Ada B}, 20{Bush B}, 61{Peter B}, 40{Walton B}]
3.3 测试 TreeSet
TreeSetUnit.java
package com.zj.sort.comparator;
import java.util.TreeSet;
 
public class TreeSetUnit {
    public static void main(String[] args) {
       TreeSet<Person> firstNameSet = new TreeSet<Person>(
              new FirstNameComparator());
       firstNameSet.add( new Person(20, "Tom" , "A" ));
       firstNameSet.add( new Person(20, "Jeff" , "A" ));
       firstNameSet.add( new Person(30, "Mary" , "A" ));
       firstNameSet.add( new Person(20, " Ada " , "B" ));
       firstNameSet.add( new Person(40, "Walton" , "B" ));
       firstNameSet.add( new Person(61, "Peter" , "B" ));
       firstNameSet.add( new Person(20, "Bush" , "B" ));
       System. out .println(firstNameSet);
       TreeSet<Person> lastNameSet = new TreeSet<Person>(
              new LastNameComparator());
       lastNameSet.addAll(firstNameSet);
       System. out .println(lastNameSet);
    }
}
结果:
[20{ Ada B}, 20{Bush B}, 20{Jeff A}, 30{Mary A}, 61{Peter B}, 20{Tom A}, 40{Walton B}]
[20{Jeff A}, 30{Mary A}, 20{Tom A}, 20{ Ada B}, 20{Bush B}, 61{Peter B}, 40{Walton B}]
3.4 测试 TreeMap
TreeMapUnit.java
package com.zj.sort.comparator;
import java.util.TreeMap;
 
public class TreeMapUnit {
    public static void main(String[] args) {
       TreeMap<Person, String> firstNameMap = new TreeMap<Person, String>(
              new FirstNameComparator());
       firstNameMap.put( new Person(20, "Tom" , "A" ), "Tom A" );
       firstNameMap.put( new Person(20, "Jeff" , "A" ), "Jeff A" );
       firstNameMap.put( new Person(30, "Mary" , "A" ), "Mary A" );
       firstNameMap.put( new Person(20, " Ada " , "B" ), "Ada B" );
       firstNameMap.put( new Person(40, "Walton" , "B" ), "Walton B" );
       firstNameMap.put( new Person(61, "Peter" , "B" ), "Peter B" );
       firstNameMap.put( new Person(20, "Bush" , "B" ), "Bush B" );
       System. out .println(firstNameMap);
       TreeMap<Person, String> lastNameMap = new TreeMap<Person, String>(
              new LastNameComparator());
       lastNameMap.putAll(firstNameMap);
       System. out .println(lastNameMap);
    }
}
结果:
{20{ Ada B}= Ada B, 20{Bush B}=Bush B, 20{Jeff A}=Jeff A, 30{Mary A}=Mary A, 61{Peter B}=Peter B, 20{Tom A}=Tom A, 40{Walton B}=Walton B}
{20{Jeff A}=Jeff A, 30{Mary A}=Mary A, 20{Tom A}=Tom A, 20{ Ada B}= Ada B, 20{Bush B}=Bush B, 61{Peter B}=Peter B, 40{Walton B}=Walton B}
本文出自 “ 子 孑” 博客,转载请与作者联系!
本文出自 51CTO.COM技术博客

[url]http://zhangjunhd.blog.51cto.com/113473/71579[/url]

你可能感兴趣的:(java,排序 ,职场,比较,休闲)