`
吖龙Sam
  • 浏览: 21007 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中两种比较器的实现

    博客分类:
  • Java
阅读更多

先举例说明:
例一:如果要对一组数字进行排序,可以写一个排序算法实现。
例如:
1 4 6 5 3 8
排序后:
1 3 4 5 6 8

例二:如果要对字母进行排序,则可以通过26个字母的自然顺序进行排序。
例如:
a f b e d c
排序后:
a b c d e f

但是工作中,有时不仅仅是这么简答的需求。例如要对一个员工进行排序,员工有员工编号,有薪资等。这时就需要用Java中的比较器来实现了。

Java 中提供了两种方式来实现比较:
1、java.util.Comparator<T> 接口声明了: int compare<T o1, T o2> 方法
  比较用来排序的两个参数:
  1)如果o1大于o2,则返回正整数;
  2)如果o1小于o2,则返回负整数
  3)如果o1等于o2,则返回零

2、java.lang.Comparable<T> 接口声明了: int compareTo(T o) 方法
  比较此对象与执行对象的顺序。比较规则同上,即:
  1)如果此对象大于指定对象,返回正整数
  2)如果此对象小于指定对象,返回负整数
  3)如果此对象等于指定对象,返回零

下面举个简单的例子说明。
需求:对员工进行排序,员工有员工编号和薪资。排序要求:
1)按照员工的编号id进行排序
2)如果员工的编号id相等,则按照员工的薪资进行比较

上代码:
1)先定义一个员工实体,员工实体实现了java.lang.Comparable接口,并重写compareTo(T o)方法。代码很简洁,就两个私有属性:

/**
 * 员工实体
 * @author Sam
 *
 */
public class Employee implements Comparable<Employee> {
	
	private int id;// 员工编号
	private double salary;// 员工薪资
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	
	public Employee(int id, double salary) {
		super();
		this.id = id;
		this.salary = salary;
	}
	
	// 为了输出方便,重写toString方法
	@Override
	public String toString() {
		// 简单输出信息
		return "id:"+ id + ",salary=" + salary;
	}

	// 比较此对象与指定对象的顺序
	@Override
	public int compareTo(Employee o) {
		// 比较员工编号,如果此对象的编号大于、等于、小于指定对象,则返回1、0、-1
		int result = this.id > o.id ? 1 : (this.id == o.id ? 0 : -1);
		// 如果编号相等,则比较薪资
		if (result == 0) {
			// 比较员工薪资,如果此对象的薪资大于、等于、小于指定对象,则返回1、0、-1
			result = this.salary > o.salary ? 1 : (this.salary == o.salary ? 0 : -1);
		}
		return result;
	}

}


2、主类(测试类):主类内部定义了一个员工比较器

/**
 * 测试两种比较器
 * @author Sam
 *
 */
public class TestEmployeeCompare {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		List<Employee> employees = new ArrayList<Employee>();
		employees.add(new Employee(2, 5000));
		employees.add(new Employee(1, 4500));
		employees.add(new Employee(4, 3500));
		employees.add(new Employee(5, 3000));
		employees.add(new Employee(4, 4000));
		// 内部比较器:要排序的对象要求实现了Comparable接口
		Collections.sort(employees);
		System.out.println("通过内部比较器实现:");
		System.out.println(employees);
		
		List<Employee> employees2 = new ArrayList<Employee>();
		employees2.add(new Employee(2, 5000));
		employees2.add(new Employee(1, 4500));
		employees2.add(new Employee(4, 3500));
		employees2.add(new Employee(5, 3000));
		employees2.add(new Employee(4, 4000));
		// 外部比较器:自定义类实现Comparator接口
		Collections.sort(employees2, new EmployeeComparable());
		System.out.println("通过外部比较器实现:");
		System.out.println(employees2);
	}

}

/**
 * 自定义员工比较器
 *
 */
class EmployeeComparable implements Comparator<Employee> {

	@Override
	public int compare(Employee o1, Employee o2) {
		// 比较员工编号,如果此对象的编号大于、等于、小于指定对象,则返回1、0、-1
		int result = o1.getId() > o2.getId() ? 1 : (o1.getId() == o2.getId() ? 0 : -1);
		// 如果编号相等,则比较薪资
		if (result == 0) {
			// 比较员工薪资,如果此对象的薪资大于、等于、小于指定对象,则返回1、0、-1
			result = o1.getSalary() > o2.getSalary() ? 1 : (o1.getSalary() == o2.getSalary() ? 0 : -1);
		}
		return result;
	}
	
}



程序输出结果:
为了让大家较全,我把结果拷贝下来,如下:

通过内部比较器实现:
[id:1,salary=4500.0, id:2,salary=5000.0, id:4,salary=3500.0, id:4,salary=4000.0, id:5,salary=3000.0]
通过外部比较器实现:
[id:1,salary=4500.0, id:2,salary=5000.0, id:4,salary=3500.0, id:4,salary=4000.0, id:5,salary=3000.0]

结果分析:
1)从程序输出结果中,可以很清晰的看出,两个比较器均可以实现同样的需求
2)id都为4的员工编号中,按照薪资来进行排序了

最后,总结一下两种比较器的区别:
1)如果使用内部比较器,需要比较的对象必须要实现Comparable接口,并重写compareTo(
T o)方法,否则不能直接使用Collections中的sort方法,程序会报错。因为程序不知道你要以何种方式来进行比较。
2)使用外部比较器,需要自己写一个比较器实现Comparator接口,并实现compare(T o1, T o2)方法,根据自己的需求定义比较规则。使用外部比较器这种方式比较灵活,例如现在需求是按照员工编号和薪资进行排序,以后可能按照姓名进行排序,这时只要再写一个按照姓名规则比较的比较器就可以了。
分享到:
评论

相关推荐

    Java动态代理两种实现方式

    Java提供了两种主要的动态代理实现方式:JDK自身的动态代理(基于接口)和Cglib库。 ### JDK动态代理 JDK动态代理是通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现的。Proxy类...

    java文本比较器.rar

    总的来说,"java文本比较器"是一个实用的开发工具,它通过Java编程语言实现,能够帮助开发者快速定位和理解两个Java文件之间的差异。通过解压并使用这个工具,我们可以提高代码审查的效率,更好地理解和管理我们的...

    java对象比较器

    通过上述分析可以看出,给定的比较器类提供了一种灵活的方法来比较不同类型的Java对象。它通过动态选择比较策略来确保正确地比较各种类型的对象。这种设计模式在实际开发中非常有用,特别是在需要对多种类型的数据...

    Java比较器实现方法项目案例

    Java中提供了两种比较器的实现方式:Comparable(内部比较器)和Comparator(外部比较器)。 第一种方式是Comparable(内部比较器),通过实现Comparable接口,可以使实体类具有比较的能力。Comparable接口支持泛型...

    java 通用比较类

    为了简化这个过程,Java提供了一种机制,即“比较器”(Comparator),它允许我们自定义对象的比较规则。本文将深入探讨Java中通用比较类的概念、实现方式以及它们在实际编程中的应用。 1. **比较器接口...

    java中tree的实现

    这两种集合都按照键的自然顺序或比较器的顺序进行排序。例如,使用`TreeSet`: ```java TreeSet&lt;Integer&gt; treeSet = new TreeSet(); treeSet.add(3); treeSet.add(1); treeSet.add(5); ``` `treeSet`会自动按升序...

    java 实现两张表的等值连接

    可以使用Java的`Collections.sort()`方法,提供自定义比较器以比较`id`字段。 4. **合并**:遍历已排序的两个列表,同时比较当前元素的`id`,如果相等,则合并它们的数据到一个新的结果对象中。这个过程类似于归并...

    浅谈Java中几种常见的比较器的实现方法

    本文将深入探讨Java中三种常见的比较器实现方法:覆写`equals()`方法,实现`Comparable`接口以及继承`Comparator`接口。 1. 覆写`equals()`方法: `equals()`方法是Object类中的一个基础方法,用于判断两个对象...

    java 自定义类比较器代码

    在 Java 中,比较器可以分为两种:内部比较器(Comparable)和外部比较器(Comparator)。 内部比较器(Comparable) 内部比较器是通过实现 `Comparable` 接口来实现的。该接口只有一个方法 `compareTo`,该方法...

    几种任务调度的Java实现方法与比较

    这两种工具都提供了更为丰富的调度策略和管理功能,适合于需要更高级调度机制的应用场景。 ### 总结与比较 1. **`Timer`**:适用于简单的定时任务调度场景,但由于其单线程模型,在高并发环境下可能不够稳定。 2. ...

    DynamicComparator:Java 动态比较器

    在静态比较器中,我们通常直接实现`Comparator`接口,提供一个固定的比较规则。例如,如果我们有一个`Person`类,我们可以创建一个比较年龄的`Comparator`: ```java class AgeComparator implements Comparator...

    java集合三种比较器(详解)

    Java集合框架中的比较器是用于定制排序规则的关键工具,尤其在使用`TreeSet`和`TreeMap`等基于自平衡二叉树结构的集合时。...在处理需要排序的集合时,了解和掌握这两种比较器的使用是非常重要的。

    JAVA过滤器标准代码

    而在`Test`过滤器中,则读取了`okok`参数,用于比较用户名。 - 这些参数通常在部署描述符(web.xml)中定义,提供了一种灵活的方式来自定义过滤器的行为。 2. **过滤逻辑`doFilter()`**: - `EncodFilter`的`...

    时间轮定时器java实现

    总结来说,Java中实现定时器有多种方式,包括基于最小堆和时间轮的实现。每种实现都有其优势和适用场景,选择哪种取决于你的系统需求,如任务数量、任务类型以及对性能的要求。理解和实现这些定时器机制对于提升软件...

    Java对象属性数据比较,返回变化数据

    当需要比较两个相同类型对象的属性时,我们通常会创建一个比较器(Comparator)或者自定义的方法来完成这项任务。`ObjectCompareUtil.java`很可能就是一个工具类,提供了静态方法来比较两个对象的属性差异。 在`...

    用贝叶斯分类器实现垃圾邮件分类器(C版本和Java版本)

    本文将深入探讨如何利用贝叶斯分类器来构建一个垃圾邮件分类器,分别介绍C语言和Java两种编程语言的实现方法,以及Java版本中引入哈希表提升计算效率的技术细节。 一、贝叶斯分类器基础 贝叶斯分类器是一种基于概率...

    excel比较器

    在这个Excel比较器中,Java作为基础编程语言,为实现文件操作、数据处理和用户界面提供强大的支撑。 其次,项目中涉及到了Apache POI库。POI是Java领域用于读写Microsoft Office格式档案的开源库,特别是Excel(....

    逐字比较器逐字比较器逐字比较器

    实现逐字比较器的方法通常有两种:一种是基于内存的比较,另一种是基于文件系统的比较。 1. 基于内存的比较:首先将两个文件读入内存,然后使用循环结构逐个比较它们的字节。这种方法适用于文件较小的情况,因为大...

    Swing JAVA 文件比较 工具

    Java文件比较工具是一种实用程序,它允许程序员或用户对比两个或多个文本文件或二进制文件的内容,找出它们之间的差异。这样的工具在软件开发、版本控制、代码审查以及数据比较等多个场景中非常有用。在Swing中开发...

    java比较器.md

    ### Java 比较器详解 #### 一、概述 在Java编程中,对对象进行排序是一项常见的需求。为了满足这种需求,Java提供了两种主要的比较接口:`Comparable` 和 `Comparator`。这两种接口允许开发者根据自定义逻辑来确定...

Global site tag (gtag.js) - Google Analytics