java 对比_Java:比较与排序

1.两种比较接口分析

在“集合框架”中有两种比较接口:Comparable接口和Comparator接口。Comparable是通用的接口,用户可以实现它来完成自己特定的比较,而Comparator可以看成一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成一种设计模式,将算法和数据分离。

前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。

一个类实现了Camparable接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用Sort方法排序了。

而Comparator的作用有两个:

1、如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序;

2、为了使用不同的排序标准做准备,比如:升序、降序或其他什么序。

2 Comparable接口

publicinterfaceComparable {

publicintcompareTo(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

packagecom.zj.sort.comparable;

publicclassPersonimplementsComparable {

privateintage;

privateStringname;

publicPerson(intage, String

name) {

this.age= age;

this.name= name;

}

publicintcompareTo(Person person) {

intcop =age- person.getAge();

if(cop != 0)

returncop;

else

returnname.compareTo(person.name);

}

publicintgetAge() {

returnage;

}

publicString getName() {

returnname;

}

publicinthashCode() {

intresult = 17;

result = 37 * result +age;

result = 37 * result +name.hashCode();

returnresult;

}

publicbooleanequals(Object o) {

if(!(oinstanceofPerson))

returnfalse;

Person person = (Person) o;

return(age== person.age) && (name.equals(person.name));

}

publicString toString() {

return(age+"{"+name+"}");

}

}

2.1测试Arrays.sort()方法

ArraysSortUnit.java

packagecom.zj.sort.comparable;

importjava.util.Arrays;

importcom.zj.compare.Person;

publicclassArraysSortUnit {

publicstaticvoidmain(String[] args) {

Person[] ps = {newPerson(20,"Tom"),newPerson(20,"Jeff"),

newPerson(30,"Mary"),newPerson(20,"Ada"),

newPerson(40,"Walton"),newPerson(61,"Peter"),

newPerson(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

packagecom.zj.sort.comparable;

importjava.util.Arrays;

importjava.util.Collections;

importcom.zj.compare.Person;

publicclassCollctionsSortUnit {

publicstaticvoidmain(String[] args) {

Person[] ps = {newPerson(20,"Tom"),newPerson(20,"Jeff"),

newPerson(30,"Mary"),newPerson(20,"Ada"),

newPerson(40,"Walton"),newPerson(61,"Peter"),

newPerson(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

packagecom.zj.sort.comparable;

importjava.util.TreeSet;

importcom.zj.compare.Person;

publicclassTreeSetUnit {

publicstaticvoidmain(String[] args) {

TreeSet set =newTreeSet();

set.add(newPerson(20,"Tom"));

set.add(newPerson(20,"Jeff"));

set.add(newPerson(30,"Mary"));

set.add(newPerson(20,"Ada"));

set.add(newPerson(40,"Walton"));

set.add(newPerson(61,"Peter"));

set.add(newPerson(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

packagecom.zj.sort.comparable;

importjava.util.TreeMap;

importcom.zj.compare.Person;

publicclassTreeMapUnit {

publicstaticvoidmain(String[] args) {

TreeMap map =newTreeMap();

map.put(newPerson(20,"Tom"),"Tom");

map.put(newPerson(20,"Jeff"),"Jeff");

map.put(newPerson(30,"Mary"),"Mary");

map.put(newPerson(20,"Ada"),"Ada");

map.put(newPerson(40,"Walton"),"Walton");

map.put(newPerson(61,"Peter"),"Peter");

map.put(newPerson(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接口

publicinterfaceComparator {

intcompare(T o1, T o2);

booleanequals(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

packagecom.zj.sort.comparator;

publicclassPerson {

privateStringfirstName;

privateStringlastName;

privateintage;

publicPerson(intage, String

firstName, String lastName) {

this.age= age;

this.firstName= firstName;

this.lastName= lastName;

}

publicintgetAge() {

returnage;

}

publicString getFirstName() {

returnfirstName;

}

publicString getLastName() {

returnlastName;

}

publicinthashCode() {

intresult = 17;

result = 37 * result +age;

result = 37 * result +firstName.hashCode();

result = 37 * result +lastName.hashCode();

returnresult;

}

publicbooleanequals(Object o) {

if(!(oinstanceofPerson))

returnfalse;

Person p = (Person) o;

return(age== p.age) && (firstName.equals(p.firstName))

&& (lastName.equals(p.lastName));

}

publicString toString() {

return(age+"{"+firstName+" "+lastName+"}");

}

}

下面设计两个比较器。

FirstNameComparator.java

packagecom.zj.sort.comparator;

importjava.util.Comparator;

//实现按FirstName优先排序

publicclassFirstNameComparatorimplementsComparator {

publicintcompare(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))

returnlastName1.compareTo(lastName2);

else

returnfirstName1.compareTo(firstName2);

}

}

LastNameComparator.java

packagecom.zj.sort.comparator;

importjava.util.Comparator;

//实现按LastName优先排序

publicclassLastNameComparatorimplementsComparator {

publicintcompare(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))

returnfirstName1.compareTo(firstName2);

else

returnlastName1.compareTo(lastName2);

}

}

下面通过上述两个比较器,调用Collections.sort和Arrays.sort排序,以及将其应用于有序集合TreeSet和TreeMap中。

3.1测试Arrays.sort()方法

ArraysSortUnit.java

packagecom.zj.sort.comparator;

importjava.util.Arrays;

publicclassArraysSortUnit {

publicstaticvoidmain(String[] args) {

Person[] ps = {newPerson(20,"Tom","A"),

newPerson(20,"Jeff","A"),newPerson(30,"Mary","A"),

newPerson(20,"Ada","B"),newPerson(40,"Walton","B"),

newPerson(61,"Peter","B"),newPerson(20,"Bush","B") };

System.out.println(Arrays.toString(ps));

Arrays.sort(ps,newFirstNameComparator());

System.out.println(Arrays.toString(ps));

Arrays.sort(ps,newLastNameComparator());

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

packagecom.zj.sort.comparator;

importjava.util.Arrays;

importjava.util.Collections;

publicclassCollectionsSortUnit {

publicstaticvoidmain(String[] args) {

Person[] ps = {newPerson(20,"Tom","A"),

newPerson(20,"Jeff","A"),newPerson(30,"Mary","A"),

newPerson(20,"Ada","B"),newPerson(40,"Walton","B"),

newPerson(61,"Peter","B"),newPerson(20,"Bush","B") };

System.out.println(Arrays.toString(ps));

Collections.sort(Arrays.asList(ps),newFirstNameComparator());

System.out.println(Arrays.toString(ps));

Collections.sort(Arrays.asList(ps),newLastNameComparator());

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

packagecom.zj.sort.comparator;

importjava.util.TreeSet;

publicclassTreeSetUnit {

publicstaticvoidmain(String[] args) {

TreeSet firstNameSet =newTreeSet(

newFirstNameComparator());

firstNameSet.add(newPerson(20,"Tom","A"));

firstNameSet.add(newPerson(20,"Jeff","A"));

firstNameSet.add(newPerson(30,"Mary","A"));

firstNameSet.add(newPerson(20,"Ada","B"));

firstNameSet.add(newPerson(40,"Walton","B"));

firstNameSet.add(newPerson(61,"Peter","B"));

firstNameSet.add(newPerson(20,"Bush","B"));

System.out.println(firstNameSet);

TreeSet lastNameSet =newTreeSet(

newLastNameComparator());

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

packagecom.zj.sort.comparator;

importjava.util.TreeMap;

publicclassTreeMapUnit {

publicstaticvoidmain(String[] args) {

TreeMap

firstNameMap =newTreeMap(

newFirstNameComparator());

firstNameMap.put(newPerson(20,"Tom","A"),"Tom A");

firstNameMap.put(newPerson(20,"Jeff","A"),"Jeff A");

firstNameMap.put(newPerson(30,"Mary","A"),"Mary A");

firstNameMap.put(newPerson(20,"Ada","B"),"Ada

B");

firstNameMap.put(newPerson(40,"Walton","B"),"Walton B");

firstNameMap.put(newPerson(61,"Peter","B"),"Peter B");

firstNameMap.put(newPerson(20,"Bush","B"),"Bush B");

System.out.println(firstNameMap);

TreeMap

lastNameMap =newTreeMap(

newLastNameComparator());

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}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值