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>

运行结果:

时间: 2024-09-30 20:08:44

JavaSE入门学习39:Java集合框架之比较器的相关文章

JavaSE入门学习40:Java集合框架之泛型

一Java泛型 JDK 4.0以前装入集合的类型不明确,也就是说集合中的元素,可以是任意类型的对象(对象的引用),如果把某个 对象放入集合,则会忽略它的类型,而把它当做Object处理,从而失去自己的实际类型.从集合中取出时往往需要转 型,效率低,容易产生错误.JDK 5.0泛型指的是规定了某个集合只可以存放特定类型的对象,会在编译期间进行类 型检查,也可以直接按指定类型获取集合元素. 如果我们只写一个排序方法,就能够对整型数组.字符串数组甚至支持排序的任何类型的数组进行排序,这该多 好啊.Ja

JavaSE入门学习33:Java集合框架概述

一集合框架 (1)集合的概念 现实生活中的集合:很多的事物凑在一起. 数学中的集合:具有共同属性的事物的总体. Java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象. (2)集合框架的概念 有了集合的概念,什么是集合框架呢?集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何 集合框架都包含三大块内容:对外的接口.接口的实现和对集合运算的算法. 1接口:即表示集合的抽象数据类型.接口提供了让我们对集合中所表示的内容进行单独操作的可能.接口允许 集合独立操纵其

Java集合框架学习笔记

本文为学习笔记,学习课程为慕课网Java入门第三季中的集合框架部分,若需要研究文中的代码,可前往下载.http://www.imooc.com/learn/110 1. List(Collection子接口) 1.1 实例化 List list = new ArrayList(); ??List是一个接口,不可直接实例化,通常情况下ArrayList实现类进行实例化. 1.2 增 1.2.1 add(obj) ??直接将obj对象加入List末位. 1.2.2 add(i, obj) ??将ob

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

一接口实现的多态 在上一篇博文:JavaSE入门学习20:Java面向对象之接口(interface)(一)中提到了接口的实现存在多态性,那么 这一篇主要就要分析接口实现的多态. 实例一 Test.java源文件代码: public class Test{ public static void main(String[] args){ //实现接口Singer Singer s1 = new Student("Amy"); s1.sing(); s1.sleep(); s1.study

JavaSE入门学习24:Java面向对象补充

一Java中的Object类 Object类是所有Java类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认 继承Object类. public class Person{ // } //等价于 public class Person extends Object{ // } Object类中的方法,适合所有子类. 1)toString()方法 在Object类中定义有public String toString()方法,其返回值是String类型,描述当前对

黑马程序员——JAVA集合框架学习总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- www.itheima.com 要学好java的集合框架,必须掌握此图: Java集合框架很全面,从大的来说.它包括两种类型: 1.一种是以collection为根接口的集合. 2.另一种是由map为根接口的<key,value>的“图”. 而collection之下的set接口和list接口又有不同: 1.Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制.

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

继续接着Java基础语法来:JavaSE入门学习5:Java基础语法(一)和JavaSE入门学习6:Java基础语法(二). 语句 Java经常使用的3种循环:while.do...while,for. (5)Java循环语句之while 语法: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 运行

黑马程序员------Java集合框架学习总结

Java培训.Android培训.iOS培训..Net培训.期待您的交流 一.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量).(数组既可以保存基本类型的数据也可以保存对象). Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些接口或实现类. 二.Collection接口 Collction: List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引.

JavaSE入门学习6:Java基础语法之运算符和语句(上)

继续接着上篇:JavaSE入门学习5:Java基础语法(一)来看Java的基础语法. 五运算符 运算符是一种"功能"符号,用以通知Java进行相关的运算.比方.我们须要将变量age的值设置为20.这时候就 须要一个"=",告诉程序须要进行赋值操作. Java 语言中经常使用的运算符可分为例如以下几种:算术运算符,赋值运算符,比較运算符,逻辑运算符,条件运符. (1)算术运算符 算术运算符主要用于进行主要的算术运算.如加法.减法.乘法.除法等. Java 中经常使用的