JavaSE入门学习39:Java集合框架之比较器
Posted life is wonderful
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE入门学习39:Java集合框架之比较器相关的知识,希望对你有一定的参考价值。
排序的算法是我们最常用的算法,初学程序,每个人都尝试过排序。但只是局限于简单的排序。
如将下列数字进行排序
1,3,5,8,3,6于是我们得出结果
1,3,3,5,6,8将下列字母(字符)进行排序
a,i,e,f,w,s
于是我们得出结果
a,e,f,i,s,w但是我们遇到的情况就不是如此简单了。如给公司里的商品进行排序,我们很轻易的想到按照商品的名称排序不
就完了,而且简单明了。但现实并如我们相信般简单。同一商品名称可以有不同的批次,进货时间,可能还会有单价
的不同。显然只根据商品名称排序是不合理的。
Java的比较器有两类,分别是Comparable接口和Comparator接口。在为对象数组进行排序时,比较器的作用非
常明显。
一Comparable接口——可比较接口
Comparable实现该接口的提示:这个类的实例可以比较大小,可以进行自然排序,定义了默认的比较规则。
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo()
方法被称为它的自然比较方法。
实现此接口的对象可以通过Collections.sort()和Arrays.sort()进行自动排序,也可以用作有序映射中的键或有序集合
中的元素,无需指定比较器。
compareTo()方法返回正数表示大,负数表示小,0表示相等。
comparable接口定义的方法:
接口声明:
<span style="font-size:18px;">public interface Comparable<T>{
int compareTo(T o);
}</span>
二Comparator接口——比较器接口
Comparator接口用于定义临时比较规则,而不是默认比较规则。可以将Comparator传递给sort()方法,从而允许
在排序顺序上实现精确控制。还可为那些没有自然顺序的对象collection提供排序。
Comparator接口比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或
正整数。
Comparator接口的方法:
接口声明:
<span style="font-size:18px;">public interface Comparator<T>{
int compare(T o1, T o2);
}</span>
三示例
所有可以排序的类都实现了java.lang.Comparable接口,Comparable接口与中只有一个方法compareTo(Object
obj),该方法:返回0表示this=obj;返回整数表示this>obj;返回负数表示this<obj。实现了Comparable接口的类通过
实现compareTo()方法从而确定该类对象的排序方式。
(1)使用Comparable接口
让需要进行排序的类实现Comparable接口,重写其中的compareTo(T o)方法,在其中定义排序规则,那么就可以
直接调用Collections.sort()来排序对象集合,实例如下:
<span style="font-size:18px;">import java.util.*;
public class Test{
public static void main(String[] args){
List l1 = new ArrayList();
l1.add(new Name("Karl","M"));
l1.add(new Name("Steven","Lee"));
l1.add(new Name("John","O"));
l1.add(new Name("Tom","M"));
//排序前遍历
for(Object o:l1){
System.out.println(o);
}
//排序
Collections.sort(l1);
System.out.println("---------------");
//排序后遍历
for(Object o:l1){
System.out.println(o);
}
}
}
class Name implements Comparable{
private String firstName;
private String lastName;
public Name(String firstName,String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String toString(){
return firstName + " " +lastName;
}
public boolean equals(Object obj){
if(obj instanceof Name){
Name name = (Name)obj;
return (firstName.equals(name.firstName))&&(lastName.equals(name.lastName));
}else{
return super.equals(obj);
}
}
public int hashCode(){
return firstName.hashCode();
}
public int compareTo(Object o){
Name n = (Name)o;
int lastCmp = lastName.compareTo(n.lastName);
return (lastCmp!=0?lastCmp:firstName.compareTo(n.firstName));
}
}</span>
运行结果:
(2)使用Comparator接口
如果对java比较熟悉的会知道java.util.Comparator接口。要实现里面的函数 int compare(Object o1, Object o2)返
回一个基本类型的整型,返回负数表示o1 小于o2,返回0 表示o1和o2相等,返回正数表示o1大于o2。
再举个简单例子然后用程序实现。如公司要将员工进行排序(不要说领导排在前面),假设我们的需求比较复杂。先
进行姓排序,谁的姓拼音靠前,谁就排前面。然后对名字进行排序。恩.如果同名,女性排前头。如果名字和性别都相
同,年龄小的排前头。ok,一个也不算复杂的需求。
网上案例经过改写的实例:
于是我们设计的人员类要有几个变量,firstname,lastname,sex,age分别表示姓,名,性别,年龄。 Person.java
源文件代码:
<span style="font-size:18px;">public class Person {
String firstname,lastname;
Boolean sex;
Integer age;
public Person(String firstname,String lastname,Boolean sex,Integer age) {
this.firstname = firstname;
this.lastname = lastname;
this.sex = sex;
this.age = age;
}
public String getFirstName(){
return firstname;
}
public String getLastName(){
return lastname;
}
public Boolean getSex(){
return sex;
}
public Integer getAge(){
return age;
}
//为了输入方便,重写了toString()
public String toString(){
return firstname +" "+lastname+" "+(sex.booleanValue()?"男":"女")+" "+age;
}
} </span>
下面是要实现比较器,Comparators.java源文件代码:
<span style="font-size:18px;">import java.util.*;
public class Comparators{
public static java.util.Comparator getComparator(){
return new java.util.Comparator(){
public int compare(Object o1, Object o2){
if(o1 instanceof String){
return compare((String)o1,(String)o2);
}else if (o1 instanceof Integer) {
return compare( (Integer) o1, (Integer) o2);
}else if (o1 instanceof Person) {
return compare( (Person) o1, (Person) o2);
}else {
System.err.println("未找到合适的比较器");
return 1;
}
}
public int compare(String o1, String o2){
String s1 = (String) o1;
String s2 = (String) o2;
int len1 = s1.length();
int len2 = s2.length();
int n = Math.min(len1, len2);
char v1[] = s1.toCharArray();
char v2[] = s2.toCharArray();
int pos = 0;
while(n-- != 0){
char c1 = v1[pos];
char c2 = v2[pos];
if(c1 != c2){
return c1 - c2;
}
pos++;
}
return len1 - len2;
}
public int compare(Integer o1, Integer o2){
int val1 = o1.intValue();
int val2 = o2.intValue();
return (val1 < val2 ? -1 : (val1 == val2 ? 0 : 1));
}
public int compare(Boolean o1, Boolean o2){
return (o1.equals(o2)? 0 : (o1.booleanValue()==true?1:-1));
}
public int compare(Person o1, Person o2){
String firstname1 = o1.getFirstName();
String firstname2 = o2.getFirstName();
String lastname1 = o1.getLastName();
String lastname2 = o2.getLastName();
Boolean sex1 = o1.getSex();
Boolean sex2 = o2.getSex();
Integer age1 = o1.getAge();
Integer age2 = o2.getAge();
return (compare(firstname1, firstname2) == 0 ?
(compare(lastname1, lastname2) == 0 ? (compare(sex1, sex2) == 0 ? (compare(age1, age2) == 0 ? 0 :
compare(age1, age2)) :
compare(sex1, sex2)) :
compare(lastname1, lastname2)) :
compare(firstname1, firstname2));
}
};
}
} </span>
测试:
<span style="font-size:18px;">import java.util.*;
public class Test{
public static void main(String[] args){
List l1 = new ArrayList();
l1.add(new Person("ouyang", "feng", Boolean.TRUE, new Integer(27)));
l1.add(new Person("zhuang", "gw", Boolean.TRUE, new Integer(27)));
l1.add(new Person("zhuang", "gw", Boolean.FALSE, new Integer(27)));
l1.add(new Person("zhuang", "gw", Boolean.FALSE, new Integer(2)));
for(Object o:l1){
System.out.println(o);
}
Collections.sort(l1, Comparators.getComparator());
System.out.println("---------------");
for(Object o:l1){
System.out.println(o);
}
}
} </span>
运行结果:
以上是关于JavaSE入门学习39:Java集合框架之比较器的主要内容,如果未能解决你的问题,请参考以下文章
JavaSE入门学习20:Java面向对象之接口(interface)