`
dawuafang
  • 浏览: 1107320 次
文章分类
社区版块
存档分类
最新评论

Java通用工具类之按对象属性排序工具类

 
阅读更多

本工具类为按对象属性排序工具类,实现的功能:
1.按对象的一个属性和多个属性进行排序.
2.按对象属性正序和倒序排列.
3.完美支持int等基础类和Integer等包装类.
4.完美支持属性为实现了Comparable接口的类.
5.如果类不是java.lang中定义的基础类型也没有实现Comparable接口则转为String后进行排序.

实现思路:使用反射取得对象属性或对象方法的值从而解除对具体对象的依赖.


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * 通用工具类之按对象中某属性排序
 * @author 李坤 
 * 交流博客:http://blog.csdn.net/lk_blog
 */
public class SortListUtil {
	public static final String DESC = "desc";
	public static final String ASC = "asc";

	/**
	 * 对list中的元素按升序排列.
	 * 
	 * @param list
	 *            排序集合
	 * @param field
	 *            排序字段
	 * @return
	 */
	public static List<?> sort(List<?> list, final String field) {
		return sort(list, field, null);
	}

	/**
	 * 对list中的元素进行排序.
	 * 
	 * @param list
	 *            排序集合
	 * @param field
	 *            排序字段
	 * @param sort
	 *            排序方式: SortList.DESC(降序) SortList.ASC(升序).
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<?> sort(List<?> list, final String field,
			final String sort) {
		Collections.sort(list, new Comparator() {
			public int compare(Object a, Object b) {
				int ret = 0;
				try {
					Field f = a.getClass().getDeclaredField(field);
					f.setAccessible(true);
					Class<?> type = f.getType();

					if (type == int.class) {
						ret = ((Integer) f.getInt(a)).compareTo((Integer) f
								.getInt(b));
					} else if (type == double.class) {
						ret = ((Double) f.getDouble(a)).compareTo((Double) f
								.getDouble(b));
					} else if (type == long.class) {
						ret = ((Long) f.getLong(a)).compareTo((Long) f
								.getLong(b));
					} else if (type == float.class) {
						ret = ((Float) f.getFloat(a)).compareTo((Float) f
								.getFloat(b));
					} else if (type == Date.class) {
						ret = ((Date) f.get(a)).compareTo((Date) f.get(b));
					} else if (isImplementsOf(type, Comparable.class)) {
						ret = ((Comparable) f.get(a)).compareTo((Comparable) f
								.get(b));
					} else {
						ret = String.valueOf(f.get(a)).compareTo(
								String.valueOf(f.get(b)));
					}

				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (NoSuchFieldException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				if (sort != null && sort.toLowerCase().equals(DESC)) {
					return -ret;
				} else {
					return ret;
				}

			}
		});
		return list;
	}

	/**
	 * 对list中的元素按fields和sorts进行排序,
	 * fields[i]指定排序字段,sorts[i]指定排序方式.如果sorts[i]为空则默认按升序排列.
	 * 
	 * @param list
	 * @param fields
	 * @param sorts
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<?> sort(List<?> list, String[] fields, String[] sorts) {
		if (fields != null && fields.length > 0) {
			for (int i = fields.length - 1; i >= 0; i--) {
				final String field = fields[i];
				String tmpSort = ASC;
				if (sorts != null && sorts.length > i && sorts[i] != null) {
					tmpSort = sorts[i];
				}
				final String sort = tmpSort;
				Collections.sort(list, new Comparator() {
					public int compare(Object a, Object b) {
						int ret = 0;
						try {
							Field f = a.getClass().getDeclaredField(field);
							f.setAccessible(true);
							Class<?> type = f.getType();
							if (type == int.class) {
								ret = ((Integer) f.getInt(a))
										.compareTo((Integer) f.getInt(b));
							} else if (type == double.class) {
								ret = ((Double) f.getDouble(a))
										.compareTo((Double) f.getDouble(b));
							} else if (type == long.class) {
								ret = ((Long) f.getLong(a)).compareTo((Long) f
										.getLong(b));
							} else if (type == float.class) {
								ret = ((Float) f.getFloat(a))
										.compareTo((Float) f.getFloat(b));
							} else if (type == Date.class) {
								ret = ((Date) f.get(a)).compareTo((Date) f
										.get(b));
							} else if (isImplementsOf(type, Comparable.class)) {
								ret = ((Comparable) f.get(a))
										.compareTo((Comparable) f.get(b));
							} else {
								ret = String.valueOf(f.get(a)).compareTo(
										String.valueOf(f.get(b)));
							}

						} catch (SecurityException e) {
							e.printStackTrace();
						} catch (NoSuchFieldException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}

						if (sort != null && sort.toLowerCase().equals(DESC)) {
							return -ret;
						} else {
							return ret;
						}
					}
				});
			}
		}
		return list;
	}

	/**
	 * 默认按正序排列
	 * 
	 * @param list
	 * @param method
	 * @return
	 */
	public static List<?> sortByMethod(List<?> list, final String method) {
		return sortByMethod(list, method, null);
	}

	@SuppressWarnings("unchecked")
	public static List<?> sortByMethod(List<?> list, final String method,
			final String sort) {
		Collections.sort(list, new Comparator() {
			public int compare(Object a, Object b) {
				int ret = 0;
				try {
					Method m = a.getClass().getMethod(method, null);
					m.setAccessible(true);
					Class<?> type = m.getReturnType();
					if (type == int.class) {
						ret = ((Integer) m.invoke(a, null))
								.compareTo((Integer) m.invoke(b, null));
					} else if (type == double.class) {
						ret = ((Double) m.invoke(a, null)).compareTo((Double) m
								.invoke(b, null));
					} else if (type == long.class) {
						ret = ((Long) m.invoke(a, null)).compareTo((Long) m
								.invoke(b, null));
					} else if (type == float.class) {
						ret = ((Float) m.invoke(a, null)).compareTo((Float) m
								.invoke(b, null));
					} else if (type == Date.class) {
						ret = ((Date) m.invoke(a, null)).compareTo((Date) m
								.invoke(b, null));
					} else if (isImplementsOf(type, Comparable.class)) {
						ret = ((Comparable) m.invoke(a, null))
								.compareTo((Comparable) m.invoke(b, null));
					} else {
						ret = String.valueOf(m.invoke(a, null)).compareTo(
								String.valueOf(m.invoke(b, null)));
					}

					if (isImplementsOf(type, Comparable.class)) {
						ret = ((Comparable) m.invoke(a, null))
								.compareTo((Comparable) m.invoke(b, null));
					} else {
						ret = String.valueOf(m.invoke(a, null)).compareTo(
								String.valueOf(m.invoke(b, null)));
					}

				} catch (NoSuchMethodException ne) {
					System.out.println(ne);
				} catch (IllegalAccessException ie) {
					System.out.println(ie);
				} catch (InvocationTargetException it) {
					System.out.println(it);
				}

				if (sort != null && sort.toLowerCase().equals(DESC)) {
					return -ret;
				} else {
					return ret;
				}
			}
		});
		return list;
	}

	@SuppressWarnings("unchecked")
	public static List<?> sortByMethod(List<?> list, final String methods[],
			final String sorts[]) {
		if (methods != null && methods.length > 0) {
			for (int i = methods.length - 1; i >= 0; i--) {
				final String method = methods[i];
				String tmpSort = ASC;
				if (sorts != null && sorts.length > i && sorts[i] != null) {
					tmpSort = sorts[i];
				}
				final String sort = tmpSort;
				Collections.sort(list, new Comparator() {
					public int compare(Object a, Object b) {
						int ret = 0;
						try {
							Method m = a.getClass().getMethod(method, null);
							m.setAccessible(true);
							Class<?> type = m.getReturnType();
							if (type == int.class) {
								ret = ((Integer) m.invoke(a, null))
										.compareTo((Integer) m.invoke(b, null));
							} else if (type == double.class) {
								ret = ((Double) m.invoke(a, null))
										.compareTo((Double) m.invoke(b, null));
							} else if (type == long.class) {
								ret = ((Long) m.invoke(a, null))
										.compareTo((Long) m.invoke(b, null));
							} else if (type == float.class) {
								ret = ((Float) m.invoke(a, null))
										.compareTo((Float) m.invoke(b, null));
							} else if (type == Date.class) {
								ret = ((Date) m.invoke(a, null))
										.compareTo((Date) m.invoke(b, null));
							} else if (isImplementsOf(type, Comparable.class)) {
								ret = ((Comparable) m.invoke(a, null))
										.compareTo((Comparable) m.invoke(b,
												null));
							} else {
								ret = String.valueOf(m.invoke(a, null))
										.compareTo(
												String.valueOf(m
														.invoke(b, null)));
							}

						} catch (NoSuchMethodException ne) {
							System.out.println(ne);
						} catch (IllegalAccessException ie) {
							System.out.println(ie);
						} catch (InvocationTargetException it) {
							System.out.println(it);
						}

						if (sort != null && sort.toLowerCase().equals(DESC)) {
							return -ret;
						} else {
							return ret;
						}
					}
				});
			}
		}
		return list;
	}

	/**
	 * 判断对象实现的所有接口中是否包含szInterface
	 * 
	 * @param clazz
	 * @param szInterface
	 * @return
	 */
	public static boolean isImplementsOf(Class<?> clazz, Class<?> szInterface) {
		boolean flag = false;

		Class<?>[] face = clazz.getInterfaces();
		for (Class<?> c : face) {
			if (c == szInterface) {
				flag = true;
			} else {
				flag = isImplementsOf(c, szInterface);
			}
		}

		if (!flag && null != clazz.getSuperclass()) {
			return isImplementsOf(clazz.getSuperclass(), szInterface);
		}

		return flag;
	}

	public static void main(String[] args) throws Exception {
		List<Student> list = new ArrayList<Student>();

		list.add(new Student(3, "b", 1, new Date(11110000)));
		list.add(new Student(1, "c", 3, new Date(44440000)));
		list.add(new Student(2, "a", 2, new Date(22210000)));
		list.add(new Student(4, "a", 11, new Date(33330000)));
		System.out.println("-------原来序列-------------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// 按age正序排序,注意结果排完后是1,2,3,11. 不是1,11,2,3(如果是String类型正序排序是这样)
		SortListUtil.sort(list, "age", null);
		System.out.println("---------测试Integer和正序,按age正序排序-----------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// 按id倒序
		SortListUtil.sort(list, "id", SortListUtil.DESC);
		System.out.println("--------测试int和倒序,按id倒序------------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// 先按name正序排序,再按id正序排序
		SortListUtil.sort(list, new String[] { "name", "id" }, new String[] {});
		System.out
				.println("---------测试多个排序字段,先按name正序,name相同时再按id正序-----------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// 先按name正序排序,再按id倒序排序
		SortListUtil.sort(list, new String[] { "name", "id" }, new String[] {
				SortListUtil.ASC, SortListUtil.DESC });
		System.out
				.println("---------测试多个排序字段,先按name正序,name相同时再按id倒序-----------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// 按birthday排序
		SortListUtil.sort(list, "birthday");
		System.out
				.println("---------测试实现了Comparable接口的对象排序,按birthday正序-----------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

		// sortByMethod
		SortListUtil.sortByMethod(list, "getId", null);
		System.out
				.println("---------测试sortByMethod,按getId方法正序-----------------");
		for (Student stu : list) {
			System.out.println(stu.toString());
		}

	}
}
测试执行效果:


Studeng.java:

import java.util.*;

public class Student{
	private int id;

	private String name;

	private Integer age;

	private Date birthday;

	public Student(int id, String name, Integer age, Date birthday) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}

	public int getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age
				+ ", birthday=" + birthday + "]";
	}


}


以下关于Comparable和Comparator的基础知识摘自博客:http://uule.iteye.com/blog/766688

1.Comparable接口是在java.lang类中的,而Comparator接口是在java.util类中的。
2.Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

用自定义类实现 Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。

而Comparator比较灵活,它没有和任何类绑定,实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现 Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。


限于本人水平有限,很多地方写的并不完美,希望大家不吝赐教.不足之处欢迎留言交流,希望在和大家的交流中得到提高.

分享到:
评论

相关推荐

    通用工具类

    8.利用反射机制进行排序工具类,支持数组、List、Set、Map的排序,可以支持多属性排序,支持子对象中的属性排序(例user对象中的role的name属性进行排序,method="role.name") 9.JVM参数获取工具 10.Java对象比较、...

    JAVA SortList 通用排序类

    JAVA SortList 通用排序类 从网上搜到一个java 对 List 排序的工具,自己改了下 支持 整数 和 浮点数 比较后排序,浮点数小数部分的有点问题,期待大牛帮忙优化。

    JAVA上百实例源码以及开源项目

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    JAVA上百实例源码以及开源项目源代码

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    java 编程入门思考

    8.1.1 数组和第一类对象 8.1.2 数组的返回 8.2 集合 8.2.1 缺点:类型未知 8.3 枚举器(反复器) 8.4 集合的类型 8.4.1 Vector 8.4.2 BitSet 8.4.3 Stack 8.4.4 Hashtable 8.4.5 再论枚举器 8.5 排序 8.6 通用集合库...

    Java初学者入门教学

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    java联想(中文)

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    包含通用对象类的库叫作类库。 2.2.7 多态型 面向对象程序的最后一个概念是多态性。凭借多态性,你可以创建一个新的对象,它具 有与基对象相同的功能,但是这些功能中的一个或多个是通过不同的方式完成...

    JAVA_Thinking in Java

    8.1.1 数组和第一类对象 8.1.2 数组的返回 8.2 集合 8.2.1 缺点:类型未知 8.3 枚举器(反复器) 8.4 集合的类型 8.4.1 Vector 8.4.2 BitSet 8.4.3 Stack 8.4.4 Hashtable 8.4.5 再论枚举器 8.5 排序 8.6 通用集合库...

    Thinking in Java简体中文(全)

    8.1.1 数组和第一类对象 8.1.2 数组的返回 8.2 集合 8.2.1 缺点:类型未知 8.3 枚举器(反复器) 8.4 集合的类型 8.4.1 Vector 8.4.2 BitSet 8.4.3 Stack 8.4.4 Hashtable 8.4.5 再论枚举器 8.5 排序 8.6 通用集合库...

    Thinking in Java 中文第四版+习题答案

    8.1.1 数组和第一类对象 8.1.2 数组的返回 8.2 集合 8.2.1 缺点:类型未知 8.3 枚举器(反复器) 8.4 集合的类型 8.4.5 再论枚举器 8.5 排序 8.6 通用集合库 8.7 新集合 8.7.1 使用 8.7.2 使用 8.7.3 使用 8.7.4 ...

    Java2核心技术.part5

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm ------------------------------------------------- 本教程由yyc,spirit整理 ------------------------------------------------- “Thinking in Java...

    Java开发技术大全 电子版

    第13章常用工具类391 13.1Runtime类的使用391 13.1.1内存管理392 13.1.2执行其他程序393 13.2System类的使用395 13.2.1利用currentTimeMillis()记录程序执行的时间395 13.2.2利用exit()退出虚拟机396 13.2.3...

    Think in Java(中文版)chm格式

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调...

    Java2核心技术.part3

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝...

    Java2核心技术.part1

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝性 1. 2.6...

    Java2核心技术.part6

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝...

Global site tag (gtag.js) - Google Analytics