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)

java学习笔记之java如何快速入门

JavaSE入门学习7:Java基础语法之语句(下)

Java集合框架之Set,Map

JavaSE入门学习21:Java面向对象之接口(interface)

JavaSE - 集合类-工具类