我的Java开发学习之旅------>Java利用Comparator接口对多个排序条件进行处理
一、需求
假设现在有个如此的需求:需要对一个这样的雇员列表进行排序,排序规则如下:
1、首先级别最高的排在前面,
2、如果级别相等,那么按工资排序,工资高的排在前面,
3、如果工资相当则按入职年数排序,入职时间最长的排在前面。
雇员对象包含级别、工资和入职年份,代码如下:
/**
* 雇员
*/
class Employee {
/**
* ID
*/
public int id;
/**
* 级别
*/
public int level;
/**
* 工资
*/
public int salary;
/**
* 入职年数
*/
public int year;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public Employee(int id, int level, int salary, int year) {
this.id = id;
this.level = level;
this.salary = salary;
this.year = year;
}
}
二、实现Comparator接口
这里我们实现java.util.Comparator接口,用于对雇员列表进行排序,代码如下:
private Comparator<Employee> comparator = new Comparator<Employee>() {
@Override
public int compare(Employee employee1, Employee employee2) {
int cr = 0;
//按级别降序排列
int a = employee2.getLevel() - employee1.getLevel();
if (a != 0) {
cr = (a > 0) ? 3 : -1;
} else {
//按薪水降序排列
a = employee2.getSalary() - employee1.getSalary();
if (a != 0) {
cr = (a > 0) ? 2 : -2;
} else {
//按入职年数降序排列
a = employee2.getYear() - employee1.getYear();
if (a != 0) {
cr = (a > 0) ? 1 : -3;
}
}
}
return cr;
}
};
三、验证排序结果
下面用一个单元测试,来验证排序结果是否正确
@Test
public void sortTest() throws Exception {
List<Employee> employeeList = new ArrayList<Employee>() {{
add(new Employee(1, 9, 10000, 10));
add(new Employee(2, 9, 12000, 7));
add(new Employee(3, 5, 10000, 12));
add(new Employee(4, 5, 10000, 6));
add(new Employee(5, 3, 5000, 3));
add(new Employee(6, 1, 2500, 1));
add(new Employee(7, 5, 8000, 10));
add(new Employee(8, 3, 8000, 2));
add(new Employee(9, 1, 3000, 5));
add(new Employee(10, 1, 2500, 4));
add(new Employee(11, 2, 2000, 4));
}};
Collections.sort(employeeList, comparator);
System.out.println("ID\tLevel\tSalary\tYears");
System.out.println("=============================");
for (Employee employee : employeeList) {
System.out.printf("%d\t%d\t%d\t%d\n", employee.getId(), employee.getLevel(), employee.getSalary(), employee.getYear());
}
System.out.println("=============================");
}
整个完整代码如下所示:
/**
* 1、首先级别最高的排在前面,<br/>
2、如果级别相等,那么按工资排序,工资高的排在前面,<br/>
3、如果工资相当则按入职年数排序,入职时间最长的排在前面。<br/>
*<p/>
*created by OuyangPeng on 2016/8/2. <a href="http://blog.csdn.net/ouyang_peng">http://blog.csdn.net/ouyang_peng</a>
*/
public class SortTest2 {
/**
* 雇员
*/
class Employee {
/**
* ID
*/
public int id;
/**
* 级别
*/
public int level;
/**
* 工资
*/
public int salary;
/**
* 入职年数
*/
public int year;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public Employee(int id, int level, int salary, int year) {
this.id = id;
this.level = level;
this.salary = salary;
this.year = year;
}
}
private Comparator<Employee> comparator = new Comparator<Employee>() {
@Override
public int compare(Employee employee1, Employee employee2) {
int cr = 0;
//按级别降序排列
int a = employee2.getLevel() - employee1.getLevel();
if (a != 0) {
cr = (a > 0) ? 3 : -1;
} else {
//按薪水降序排列
a = employee2.getSalary() - employee1.getSalary();
if (a != 0) {
cr = (a > 0) ? 2 : -2;
} else {
//按入职年数降序排列
a = employee2.getYear() - employee1.getYear();
if (a != 0) {
cr = (a > 0) ? 1 : -3;
}
}
}
return cr;
}
};
@Test
public void sortTest() throws Exception {
List<Employee> employeeList = new ArrayList<Employee>() {{
add(new Employee(1, 9, 10000, 10));
add(new Employee(2, 9, 12000, 7));
add(new Employee(3, 5, 10000, 12));
add(new Employee(4, 5, 10000, 6));
add(new Employee(5, 3, 5000, 3));
add(new Employee(6, 1, 2500, 1));
add(new Employee(7, 5, 8000, 10));
add(new Employee(8, 3, 8000, 2));
add(new Employee(9, 1, 3000, 5));
add(new Employee(10, 1, 2500, 4));
add(new Employee(11, 2, 2000, 4));
}};
Collections.sort(employeeList, comparator);
System.out.println("ID\tLevel\tSalary\tYears");
System.out.println("=============================");
for (Employee employee : employeeList) {
System.out.printf("%d\t%d\t%d\t%d\n", employee.getId(), employee.getLevel(), employee.getSalary(), employee.getYear());
}
System.out.println("=============================");
}
}
运行结果:
ID Level Salary Years
=============================
2 9 12000 7
1 9 10000 10
3 5 10000 12
4 5 10000 6
7 5 8000 10
8 3 8000 2
5 3 5000 3
11 2 2000 4
9 1 3000 5
10 1 2500 4
6 1 2500 1
=============================
验证第一条件:首先按级别排序,级别最高的排在前面
从上面的运行结果可以发现,还是满足需求第一条要求的:首先按级别排序,级别最高的排在前面
1、首先从整体来看,是从级别最高的9级排序到级别最低的1级
ID Level Salary Years
=============================
2 9 12000 7
1 9 10000 10
3 5 10000 12
4 5 10000 6
7 5 8000 10
8 3 8000 2
5 3 5000 3
11 2 2000 4
9 1 3000 5
10 1 2500 4
6 1 2500 1
=============================
验证第二条:如果级别相等,那么按工资排序,工资高的排在前面
2、当级别相同的情况下,如下两天记录:
2 9 12000 7
1 9 10000 10
则都是9级,这个时候是满足第二条要求的:如果级别相等,那么按工资排序,工资高的排在前面
下面的3条记录也是满足第二条要求的:
9 1 3000 5
10 1 2500 4
6 1 2500 1
则都是1级,工资为3000的排在工资为2500的前面。
验证第三条:如果工资相当则按入职年数排序,入职时间最长的排在前面
3、当级别和工资都相同的情况下,则比较入职年数。如下面的两条记录
10 1 2500 4
6 1 2500 1
级别都是1级,工资都是2500,年数为4的排在年数为1的前面。这个时候是满足第三条要求的:如果工资相当则按入职年数排序,入职时间最长的排在前面
其实Comparator接口直接写成下面的就行了
private Comparator<Employee> comparator = new Comparator<Employee>() {
@Override
public int compare(Employee employee1, Employee employee2) {
int cr = 0;
//按级别降序排列
int a = employee2.getLevel() - employee1.getLevel();
if (a != 0) {
cr = (a > 0) ? 1 : -1;
} else {
//按薪水降序排列
a = employee2.getSalary() - employee1.getSalary();
if (a != 0) {
cr = (a > 0) ? 1 : -1;
} else {
//按入职年数降序排列
a = employee2.getYear() - employee1.getYear();
if (a != 0) {
cr = (a > 0) ? 1 : -1;
}
}
}
return cr;
}
};
附录:java.util.Comparator接口源代码
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.util;
/**
* A {@code Comparator} is used to compare two objects to determine their ordering with
* respect to each other. On a given {@code Collection}, a {@code Comparator} can be used to
* obtain a sorted {@code Collection} which is <i>totally ordered</i>. For a {@code Comparator}
* to be <i>consistent with equals</i>, its {code #compare(Object, Object)}
* method has to return zero for each pair of elements (a,b) where a.equals(b)
* holds true. It is recommended that a {@code Comparator} implements
* {@link java.io.Serializable}.
*
* @since 1.2
*/
public interface Comparator<T> {
/**
* Compares the two specified objects to determine their relative ordering. The ordering
* implied by the return value of this method for all possible pairs of
* {@code (lhs, rhs)} should form an <i>equivalence relation</i>.
* This means that
* <ul>
* <li>{@code compare(a,a)} returns zero for all {@code a}</li>
* <li>the sign of {@code compare(a,b)} must be the opposite of the sign of {@code
* compare(b,a)} for all pairs of (a,b)</li>
* <li>From {@code compare(a,b) > 0} and {@code compare(b,c) > 0} it must
* follow {@code compare(a,c) > 0} for all possible combinations of {@code
* (a,b,c)}</li>
* </ul>
*
* @param lhs
* an {@code Object}.
* @param rhs
* a second {@code Object} to compare with {@code lhs}.
* @return an integer < 0 if {@code lhs} is less than {@code rhs}, 0 if they are
* equal, and > 0 if {@code lhs} is greater than {@code rhs}.
* @throws ClassCastException
* if objects are not of the correct type.
*/
public int compare(T lhs, T rhs);
/**
* Compares this {@code Comparator} with the specified {@code Object} and indicates whether they
* are equal. In order to be equal, {@code object} must represent the same object
* as this instance using a class-specific comparison.
* <p>
* A {@code Comparator} never needs to override this method, but may choose so for
* performance reasons.
*
* @param object
* the {@code Object} to compare with this comparator.
* @return boolean {@code true} if specified {@code Object} is the same as this
* {@code Object}, and {@code false} otherwise.
* @see Object#hashCode
* @see Object#equals
*/
public boolean equals(Object object);
}
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
我的Java开发学习之旅------>Java利用Comparator接口对多个排序条件进行处理的更多相关文章
- 我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法
本文参考: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html http://www.blogjava.net/ ...
- 我的Java开发学习之旅------>Java使用Fork/Join框架来并行执行任务
现代的计算机已经向多CPU方向发展,即使是普通的PC,甚至现在的智能手机.多核处理器已被广泛应用.在未来,处理器的核心数将会发展的越来越多. 虽然硬件上的多核CPU已经十分成熟,但是很多应用程序并未这 ...
- 我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常
今天在使用Java NIO的Channel和Buffer进行文件操作时候,报了java.nio.charset.MalformedInputException: Input length = 1异常, ...
- 我的Java开发学习之旅------>Java使用ObjectOutputStream和ObjectInputStream序列号对象报java.io.EOFException异常的解决方法
今天用ObjectOutputStream和ObjectInputStream进行对象序列化话操作的时候,报了java.io.EOFException异常. 异常代码如下: java.io.EOFEx ...
- Java之——利用Comparator接口对多个排序条件进行处理
转载自:http://blog.csdn.net/l1028386804/article/details/56513205 膜拜大神··· 一.需求 假设现在有个如此的需求:需要对一个这样的雇员列表进 ...
- 我的Java开发学习之旅------>Java String对象作为参数传递的问题解惑
又是一道面试题,来测试你的Java基础是否牢固. 题目:以下代码的运行结果是? public class TestValue { public static void test(String str) ...
- 我的Java开发学习之旅------>Java语言中方法的参数传递机制
实参:如果声明方法时包含来了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时传给形参的参数值也被称为实参. Java的实参值是如何传入方法?这是由Java方法的参数传递机制来控制的,Java ...
- 我的Java开发学习之旅------>Java经典排序算法之归并排序
一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列 ...
- 我的Java开发学习之旅------>Java经典排序算法之快速排序
一.算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod).(1) 分治法的 ...
随机推荐
- Python内置函数之repr()
repr(object) 返回对象的字符串形式. >>> a = 'hello' >>> repr(a) "'hello'" 返回的字符串形式可 ...
- php新版本废弃 preg_replace /e 修饰符
php新版本废弃 preg_replace /e 修饰符 分类: PHP -- : 3531人阅读 评论() 收藏 举报 php正则 最近服务器php版本升级到了 5.6 发现出了很多警告 [php] ...
- 李洪强iOS开发之iOS社区收集
李洪强iOS开发之iOS社区收集 项目 简述 github 全球最大的代码仓库,无论是iOS开发还是Android开发没有人不知道这个网站,它也是一个社区,你可以去follow(关注)某些人或公司. ...
- 一次csrf配合xss的攻击实例
xss出现在我的邮箱处 alert of payload "><script>alert(/test/)</script><" by cooki ...
- Oracle 错误 maximum number of processes(150) exceeded 解决办法
网上很多同行应该都遇到过这个问题,百度一搜 千篇一律的处理办法,就是加大进程数. 但是我这边情况不一样,因为我的Oracle 11g是早上刚装的,跟本没人用,我用PLSQL链接照样说不能链接. 我就在 ...
- [Python基础]Python文件处理小结
1. 文件的打开与关闭 <1>打开文件 在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件 open(文件名,访问模式) 示例如下: f = open('te ...
- OracleHelper.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text; using System.Conf ...
- 【BZOJ】3203: [Sdoi2013]保护出题人(几何+三分+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3203 wa无数次QAQ,犯sb错....一是数组没有引用...二是输出转成了int(越界了sad). ...
- 【BZOJ】1656:[Usaco2006 Jan]The Grove 树木(bfs+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1656 神bfs! 我们知道,我们要绕这个联通的树林一圈. 那么,我们想,怎么才能让我们的bfs绕一个 ...
- js阻止表单提交
<!DOCTYPE html><html><head> <title>Simple Login Form</title> < ...