关于对List的通用排序实现

简介: List的排序大家都会想到实现Comparator接口,但是如果我们需要对list排序是动态,就比较崩溃了,复杂度不言而喻。经过仔细思索,写了一个工具类,使用反射机制实现对list对象的排序功能,专门用于List对象的排序工作。package xzknet.net.csdn.blog.utils;import java.beans.PropertyDescriptor;import j

List的排序大家都会想到实现Comparator接口,但是如果我们需要对list排序是动态,就比较崩溃了,复杂度不言而喻。经过仔细思索,写了一个工具类,使用反射机制实现对list对象的排序功能,专门用于List对象的排序工作。

package xzknet.net.csdn.blog.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;

/**
 * List排序工具
 * 
 * @author Ken.xu(mailto:xzknet@gmail.com)
 * @version 1.0 Copyright 2012-9-18 下午04:37:17
 * @param <T>
 */
public class ListSortUtil<T> {
	private Map<Method, Direction> sortField = new LinkedHashMap<Method, Direction>();
	private Map<String, Method> propertyMethodMap = null;

	// Method[] methods
	public ListSortUtil(final Class clazz) {
		PropertyDescriptor[] propertyDescriptor = BeanUtils.getPropertyDescriptors(clazz);
		Map<String, Method> propertyMethodMap = new HashMap<String, Method>();
		for (PropertyDescriptor pd : propertyDescriptor) {
			String key = pd.getName();
			Method value = pd.getReadMethod();
			propertyMethodMap.put(key, value);
		}
		this.propertyMethodMap = propertyMethodMap;
	}

	public void clear() {
		sortField.clear();
	}

	/**
	 * 增加一个降序
	 * 
	 * @param fieldName
	 * @throws NoSuchMethodException
	 * @author Ken_xu
	 */
	public void addDesc(String fieldName) throws NoSuchMethodException {
		addFieldMethod(fieldName, Direction.DESC);
	}

	/**
	 * 增加一个升序
	 * 
	 * @param fieldName
	 * @throws NoSuchMethodException
	 * @author Ken_xu
	 */
	public void addAsc(String fieldName) throws NoSuchMethodException {
		addFieldMethod(fieldName, Direction.ASC);
	}

	/**
	 * 增加一个字段排序模式
	 * 
	 * @param fieldName
	 * @param direction
	 * @throws NoSuchMethodException
	 * @author Ken_xu
	 */
	private void addFieldMethod(String fieldName, Direction direction) throws NoSuchMethodException {
		Method method = propertyMethodMap.get(fieldName);
		if (method == null) {
			throw new NoSuchMethodException(fieldName);
		} else {
			sortField.put(method, direction);
		}
	}

	public List<T> sortList(List<T> list) {
		if (sortField.isEmpty() == false) {
			Comparator<T> comparator = new Comparator<T>() {
				public int compare(T o1, T o2) {
					int flag = 0;
					for (Map.Entry<Method, Direction> entry : sortField.entrySet()) {
						Method method = entry.getKey();
						Direction direction = entry.getValue();
						if (direction == Direction.ASC) {
							// DESC:降序
							flag = this.compareByFlag(method, o1, o2);
						} else {
							// ASC:升序
							flag = this.compareByFlag(method, o2, o1);
						}
						if (flag != 0) {
							break;
						}
					}
					if (flag > 0) {
						flag = 1;
					} else if (flag < 0) {
						flag = -1;
					}
					return flag;
				}

				/**
				 * 如果t1大于t2:1<br>
				 * t1等于t2:0<br>
				 * t1小于t2:-1
				 * 
				 * @param flag
				 * @param t1
				 * @param t2
				 * @return
				 * @author Ken_xu
				 */
				private int compareByFlag(Method method, T t1, T t2) {
					int flag = 0;
					try {
						String methodReturn1 = method.invoke(t1).toString();
						String methodReturn2 = method.invoke(t2).toString();
						flag = methodReturn1.compareTo(methodReturn2);
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
					return flag;
				}

			};
			Collections.sort(list, comparator);
		}
		return list;
	}

	/**
	 * 排序方式:
	 * <p>
	 * ASC:升序<br/> DESC:降序
	 * 
	 */
	enum Direction {
		ASC, DESC
	};
}


测试用例也给大家提供一个

package xzknet.net.csdn.blog.utils;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

public class ListSortUtilTest extends TestCase {

	private List<TestUser> list = null;

	/**
	 * 打印清单
	 * 
	 * @author Ken_xu
	 */
	private void printListEg() {
		List<TestUser> TestUserList = new ArrayList<TestUser>();
		for (int i = 0, maxIdx = list.size(); i < maxIdx; i++) {
			TestUser tm = list.get(i);
			String showTxt = String.format("%d)\t modelName=%s;\t\t extendsModel=%s;", i, tm.getModelName(), tm.getExtendsModels());
			System.out.println(showTxt);
			if (i == (maxIdx - 1)) {
				showTxt = String.format("...................总共:%d条", list.size());
				System.out.println(showTxt);
			}
			TestUserList.add(tm);
		}
		list = TestUserList;
	}

	/**
	 * 初始化测试用例
	 */
	protected void setUp() throws Exception {
		super.setUp();

		List<TestUser> TestUserList = new ArrayList<TestUser>();
		long rowNum = 0l;
		for (int i = 0; i < 10; i++) {
			TestUser tm = new TestUser();
			if (i % 2 == 0) {
				// 每两个对象的modelName相同
				rowNum = Math.round(Math.random() * 100);
			}
			tm.setModelName("AAA_TEST_" + rowNum);
			tm.setExtendsModels("BBBBBBB" + i);
			TestUserList.add(tm);
		}
		list = TestUserList;
	}

	/**
	 * 测试排序
	 * 
	 * @author Ken_xu
	 */
	public void testSort() {
		ListSortUtil<TestUser> sortUtil = new ListSortUtil(TestUser.class);
		try {
			sortUtil.addDesc("modelName");
			sortUtil.addAsc("extendsModels");
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		System.out.println("打印排序前结果");
		printListEg();
		sortUtil.sortList(list);
		System.out.println("打印排序后结果");
		printListEg();
	}

	class TestUser {
		String modelName, extendsModels;

		public String getModelName() {
			return modelName;
		}

		public void setModelName(String modelName) {
			this.modelName = modelName;
		}

		public String getExtendsModels() {
			return extendsModels;
		}

		public void setExtendsModels(String extendsModels) {
			this.extendsModels = extendsModels;
		}
	}
}

 

测试结果如下:

打印排序前结果
0)	 modelName=AAA_TEST_48;		 extendsModel=BBBBBBB0;
1)	 modelName=AAA_TEST_48;		 extendsModel=BBBBBBB1;
2)	 modelName=AAA_TEST_29;		 extendsModel=BBBBBBB2;
3)	 modelName=AAA_TEST_29;		 extendsModel=BBBBBBB3;
4)	 modelName=AAA_TEST_1;		 extendsModel=BBBBBBB4;
5)	 modelName=AAA_TEST_1;		 extendsModel=BBBBBBB5;
6)	 modelName=AAA_TEST_63;		 extendsModel=BBBBBBB6;
7)	 modelName=AAA_TEST_63;		 extendsModel=BBBBBBB7;
8)	 modelName=AAA_TEST_73;		 extendsModel=BBBBBBB8;
9)	 modelName=AAA_TEST_73;		 extendsModel=BBBBBBB9;
...................总共:10条
打印排序后结果
0)	 modelName=AAA_TEST_73;		 extendsModel=BBBBBBB8;
1)	 modelName=AAA_TEST_73;		 extendsModel=BBBBBBB9;
2)	 modelName=AAA_TEST_63;		 extendsModel=BBBBBBB6;
3)	 modelName=AAA_TEST_63;		 extendsModel=BBBBBBB7;
4)	 modelName=AAA_TEST_48;		 extendsModel=BBBBBBB0;
5)	 modelName=AAA_TEST_48;		 extendsModel=BBBBBBB1;
6)	 modelName=AAA_TEST_29;		 extendsModel=BBBBBBB2;
7)	 modelName=AAA_TEST_29;		 extendsModel=BBBBBBB3;
8)	 modelName=AAA_TEST_1;		 extendsModel=BBBBBBB4;
9)	 modelName=AAA_TEST_1;		 extendsModel=BBBBBBB5;
...................总共:10条

 

相关文章
|
11月前
|
Java
【Java基础】Java8 使用 stream().sorted()对List集合进行排序
【Java基础】Java8 使用 stream().sorted()对List集合进行排序
288 0
|
25天前
|
存储 Java API
【Java高手必备】揭秘!如何优雅地对List进行排序?掌握这几种技巧,让你的代码瞬间高大上!
【8月更文挑战第23天】本文深入探讨了Java中对List集合进行排序的各种方法,包括使用Collections.sort()、自定义Comparator以及Java 8的Stream API。通过示例代码展示了不同情况下如何选择合适的方法:从简单的整数排序到自定义类对象的排序,再到利用Comparator指定特殊排序规则,最后介绍了Stream API在排序操作中的简洁应用。理解这些技术的区别与应用场景有助于提高编程效率。
19 4
|
2月前
|
Java API 存储
Java如何对List进行排序?
【7月更文挑战第26天】
97 9
Java如何对List进行排序?
|
人工智能 Java API
一文学会List函数排序操作,20秒即可完成!
假设有一个用户管理系统,其中包含两个用户列表:一个是从数据库中获取的原始用户列表,另一个是从外部API获取的新用户列表。在这种情况下,用Java函数来实现将新用户列表中的数据合并到原始用户列表中的功能。
|
4月前
|
搜索推荐 算法 C++
list容器-排序案例讲解
list容器-排序案例讲解
24 0
|
4月前
|
算法 C++ 容器
list容器-反转和排序讲解39
list容器-反转和排序讲解39
49 0
对List进行排序,值为null的排到最后
对List进行排序,值为null的排到最后
|
4月前
|
Java
Java对list集合元素进行排序的几种方式
Java对list集合元素进行排序的几种方式
52 0
|
4月前
|
C++ 容器
【C++STL基础入门】list交换、翻转,排序、合并和拼接操作
【C++STL基础入门】list交换、翻转,排序、合并和拼接操作
437 0
|
4月前
|
C++ 容器
【C++】STL容器——探究List与Vector在使用sort函数排序的区别(14)
【C++】STL容器——探究List与Vector在使用sort函数排序的区别(14)