`

Java对List多个排序、查询条件的处理

    博客分类:
  • Java
 
阅读更多

 

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ComparisonChain;

/**
 * Filter and Sort <code>List</code> by multiple conditions.<br>
 * It's like SQL 'Where' and 'Order by' clause. Input multiple <code>Comparator</code>
 * 
 * @author zheng.wen   http://www.oschina.net/question/12_21127
 * @param <T>
 */
public class GroupFilterSortUtils<T> implements Comparator<T> {
	
	/**排序方式**/
	interface Sort {
		public static final String DESC = "DESC";
		public static final String ASC = "ASC";
		
		/**数组下标0,排序条件名称**/
		public static final int NAME = 0;
		/**数组下标1,排序方式**/
		public static final int TYPE = 1;
	}
	
	/**过滤条件**/
	interface Filter {
		/**过滤模式**/
		public static final String LIKE = "0";
		public static final String START_WITH = "1";
		public static final String EQUAL = "2";
		public static final String LESS_THAN = "3";
		public static final String MORE_THAN = "4";
		
		/**大小写**/
		public static final String DIFF_CASE_TRUE = "TRUE";
		public static final String DIFF_CASE_FALSE = "FALSE";
		
		/**数组下标0,过滤条件名称**/
		public static final int NAME = 0;
		/**数组下标1,过滤条件值**/
		public static final int VALUE = 1;
		/**数组下标2,过滤模式**/
		public static final int MODE = 2;
		/**是否区分大小写**/
		public static final int IS_DIFF_CASE = 3;
	}
	
	public GroupFilterSortUtils() { }
	
	/**存储比较器: 此处不能使用static**/
	private List<Comparator<Object>> comparators = new ArrayList<Comparator<Object>>();
	
	public int compare(T t1, T t2) {
		if (t1 == null || t2 == null) return 0;
		for (Comparator<Object> comparator : comparators) {
			int returnValue = comparator.compare(t1, t2);
			if (returnValue != 0) return returnValue;
		}
		return 0;
	}
	
	public static <T> List<T> filterList(final List<T> list, final String[] ... filterChain) {
		if (list == null || list.size() <= 0 || filterChain == null || filterChain.length <=0) return list;
		if (list.contains(null)) list.remove(null);
		List<T> tempList = new ArrayList<T>();
		boolean flag;
		for (T t : list) {
			if (t == null) continue;
			flag = true;
			for (String[] filter : filterChain) {
				if (!flag) break;
				flag = false;
				
				String filterName = filter[Filter.NAME];
				String filterValue = filter[Filter.VALUE];
				String filterMode = filter[Filter.MODE];
				String isDiffUpperLowerCase = filter[Filter.IS_DIFF_CASE];
				boolean isDiffCase = Boolean.parseBoolean(isDiffUpperLowerCase);
				try {
					String methodName = "get" + firstLetterToUpper(filterName);
					Method method = t.getClass().getDeclaredMethod(methodName, null);
					Object o = method.invoke(t, null);
					String realValue = o != null ? o.toString() : "";
					
					String filterValue2 = isDiffCase ? filterValue : filterValue.toLowerCase();
					String realValue2 = isDiffCase ? realValue : realValue.toLowerCase();
					
					if ((Filter.START_WITH.equals(filterMode) && realValue2.startsWith(filterValue2)) ||
							(Filter.LIKE.equals(filterMode) && realValue2.indexOf(filterValue2) != -1) ||
							(Filter.EQUAL.equals(filterMode) && realValue2.equals(filterValue2)) ||
							(Filter.MORE_THAN.equals(filterMode) && Double.parseDouble(realValue2) > Double.parseDouble(filterValue2)) ||
							(Filter.LESS_THAN.equals(filterMode) && Double.parseDouble(realValue2) < Double.parseDouble(filterValue2))) flag = true;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (flag) tempList.add(t);
		}
		return tempList;
	}
	
	public <T> List<T> sortList(final List<T> list, final String[]... sortChain) {
		if (list == null || list.size() <= 0 || sortChain == null || sortChain.length <=0) return list;
		if (list.contains(null)) list.remove(null);
		this.setComparator(sortChain);
		List<T> tempList = new ArrayList<T>();
		tempList.addAll(list);
		Collections.sort(tempList, (GroupFilterSortUtils<T>) this);
		return tempList;
	}
	
	public <T> List<T> filterSortList(final List<T> list, final String[][] filterChain, final String[][] sortChain) {
		if (list == null || list.size() <= 0 || filterChain == null || filterChain.length <= 0 || sortChain == null || sortChain.length <=0) return list;
		if (list.contains(null)) list.remove(null);
		List<T> tempList = filterList(list, filterChain);
		this.setComparator(sortChain);
		Collections.sort(tempList, (GroupFilterSortUtils<T>) this);
		return tempList;
	}
	
	public static String firstLetterToUpper(String str){
		if (str == null || "".equals(str)) return str;
        char[] array = str.toCharArray();
        array[0] -= 32;
        return String.valueOf(array);
    }
	
	private <T> void setComparator(final String[][] sortCriteria) {
		if (sortCriteria == null || sortCriteria.length <= 0) return;

		for (final String[] criteria : sortCriteria) {
			Comparator<T> sortComparator = new Comparator<T> () {
				public int compare(T t1, T t2) {
					if (t1 == null || t2 == null) return 0;
					int result = 0;
					try {
						String name = criteria[Sort.NAME];
						String type = criteria[Sort.TYPE];
						
						Field field = t1.getClass().getDeclaredField(name);
						Type fieldType = field.getType();

						String methodName = "get" + firstLetterToUpper(name);
						Method method = t1.getClass().getDeclaredMethod(methodName, null);
						
						Object o1 = method.invoke(t1, null);
						Object o2 = method.invoke(t2, null);
						
						if (fieldType == Integer.TYPE || fieldType == Long.TYPE || fieldType == Double.TYPE || fieldType == Float.TYPE || fieldType == Short.TYPE || fieldType == Byte.TYPE) {
							result = type.equals(GroupComparator.DESC) ? (Integer) o2 - (Integer) o1 : (Integer) o1 - (Integer) o2;
						} else if (fieldType == String.class || fieldType == Character.class) {
							String str1 = o1 == null ? "" : o1.toString();
							String str2 = o2 == null ? "" : o2.toString();
							
							result = type.equals(GroupFilterSortUtils.Sort.DESC) ? str2.compareTo(str1) : str1.compareTo(str2);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					return result;
				}
			};
			comparators.add((Comparator<Object>) sortComparator);
		}	
	}
	
	public static void main(String[] args) {
		List<User> userList = new ArrayList<User>() {
			{
				add(new User(1, "aaa", 10, 5, 4004, 1));
				add(new User(2, "aac", 22, 5, 5300, 1));
				add(new User(3, "aab", 10, 4, 4800, 1));
				add(new User(4, "ccc", 33, 5, 5000, 3));
				add(new User(5, "yyy", 55, 1, 4000, 1));
				add(new User(6, "bbb", 77, 1, 5800, 4));
				add(new User(7, "qqq", 56, 2, 4000, 7));
				add(new User(8, "ece", 18, 3, 5500, 1));
				add(new User(9, "ggg", 30, 4, 7050, 3));
				add(new User(10, "vcv", 9, 2, 4560, 1));
				add(new User(11, "vcv", 9, 5, 8560, 1));
			}
		};
		
		for(int i = 0; i < 1000000; i++) {
			userList.add(new User(i+12, "kkk" + i, 40, 7, 9000, i));
		}
		
		String[][] filterChain = {
									{User.Filter.NAME, "k", GroupFilterSortUtils.Filter.LIKE, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE}, 
									{User.Filter.SALARY, "00", GroupFilterSortUtils.Filter.LIKE, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE}, 
									{User.Filter.YEAR, "30", GroupFilterSortUtils.Filter.MORE_THAN, GroupFilterSortUtils.Filter.DIFF_CASE_FALSE}
								 };
		
		String[][] sortChain = {
									{ User.Sort.NAME, GroupFilterSortUtils.Sort.ASC },
									{ User.Sort.LEVEL, GroupFilterSortUtils.Sort.DESC },
									{ User.Sort.SALARY, GroupFilterSortUtils.Sort.DESC },
									{ User.Sort.YEAR, GroupFilterSortUtils.Sort.DESC } 
							   };
		
		long start = System.currentTimeMillis();
		
		GroupFilterSortUtils<User> groupFilterSort = new GroupFilterSortUtils<User>();
		List<User> tempList = groupFilterSort.filterList(userList, filterChain);
		
		long start2 = System.currentTimeMillis();
		
		tempList = groupFilterSort.sortList(tempList, sortChain);
		
		long end = System.currentTimeMillis();
		
		System.out.println("1:" + (start2 - start) + " 2:" + (end - start2) + " 3:" + (end - start));
		System.out.println(tempList.size());
//		for (User user : tempList) {
//			System.out.println(user.getName() + " : " + user.getSalary() + " : " + user.getYear());
//		}

	}
}


class User {
	
	private int id;
	private String name;
	private int age;
	private int level;
	private int salary;
	private int year;

	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 int getAge() {
		return age;
	}

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

	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 User(int id, String name, int age, int level, int salary, int year) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.level = level;
		this.salary = salary;
		this.year = year;
	}
	
	interface Filter {
		public static final String NAME = "name";
		public static final String LEVEL = "level";
		public static final String SALARY = "salary";
		public static final String YEAR = "year";
	}
	
	interface Sort {
		public static final String NAME = "name";
		public static final String LEVEL = "level";
		public static final String SALARY = "salary";
		public static final String YEAR = "year";
	}
	
	public static void main(String[] args) {
		List<User> userList = new ArrayList<User>() {
			{
				add(new User(1, "aaa", 10, 5, 4004, 1));
				add(new User(2, "aac", 22, 5, 5300, 1));
				add(new User(3, "aab", 10, 4, 4800, 1));
				add(new User(4, "ccc", 33, 5, 5000, 3));
				add(new User(5, "yyy", 55, 1, 4000, 1));
				add(new User(6, "bbb", 77, 1, 5800, 4));
				add(new User(7, "qqq", 56, 2, 4000, 7));
				add(new User(8, "ece", 18, 3, 5500, 1));
				add(new User(9, "ggg", 30, 4, 7050, 3));
				add(new User(10, "vcv", 9, 2, 4560, 1));
				add(new User(11, "vcv", 9, 5, 8560, 1));
			}
		};
		
		for(int i = 0; i < 1000000; i++) {
			userList.add(new User(i+12, "kkk" + i, 40, 7, 9000, i));
		}
		
		long start = System.currentTimeMillis();
		
		Collection<User>  filterCollection = Collections2.filter(userList, new Predicate<User>(){
			public boolean apply(User user) {
				if (user == null) return false;
				String name = user.getName() + "";
				String salary = user.getSalary() + "";
				int year = user.getYear();
				if (name.indexOf("k") != -1 && salary.indexOf("00") != -1 && year > 30) {
					return true;
				}
				return false;
			}
		});
		
		long start2 = System.currentTimeMillis();
				
		User[] userArray = new User[filterCollection.size()];
		List<User> tempList = Arrays.asList(filterCollection.toArray(userArray));

		long start3 = System.currentTimeMillis();
		Collections.sort(tempList, new Comparator<User>(){
			public int compare(User o1, User o2) {
				if (o1 == null || o2 == null) return 0;
				return ComparisonChain.start()  
				       .compare(o1.getName(), o2.getName())  
				       .compare(o1.getLevel(), o2.getLevel()) 
				       .compare(o2.getSalary(), o1.getSalary())
				       .compare(o1.getYear(), o2.getYear()).result(); 
			}
		});
		
		long end = System.currentTimeMillis();
		
		System.out.println("1:" + (start2 - start) + " 2:" + (start3 - start2) + " 3:" + (end - start3) + " all:" + (end - start));
		System.out.println(tempList.size());
		
//		for (User user : tempList) {
//			System.out.println(user.getName() + " : " + user.getSalary() + " : " + user.getYear());
//		}
		
		
	}
}
分享到:
评论

相关推荐

    java List中对象多属性排序及各属性排序设置

    天才之作:通过泛型,对List中对象多属性排序,支持设置各属性排序方式(动态属性),看了之后绝对让你震撼!

    java List排序工具类

    // 构造多个person对象为排序提供数据 Person person = new Person(); person.setName("wtt"); person.setSex("男"); person.setAge(24); Person person1 = new Person(); person1.setName("wjj"); person1....

    List&lt;map&gt;多字段组合排序

    List,List, Object&gt;&gt;,多字段组合排序。提供一个简易的思路,如果需要进行参考。

    java List排序demo

    有时候我们可能有这样的需求:将一个List按照某个字段进行排序。比如现在有多个Student,我们要将这些学生按照成绩(grad)进行排序,本demo就是一个将List排序的demo

    Java将2个List集合合并到一个List里面并排序工具类

    Java将2个List集合合并到一个List里面并排序工具类 1、Java编程资源,定义了一个名为`ListMerger`的工具类,主要包含一个名为`mergeAndSortLists`的静态方法。此方法用于将两个已经根据时间顺序排列的List合并成一...

    List<Map>中英文排序

    支持一个List按照MAP中的一个或者多个Key的value值的中英文来排序,自动识别字符和数字(包括[a-zA-z]?[0-9]*)排序

    java实现把一个List集合拆分成多个的操作

    主要介绍了java实现把一个List集合拆分成多个的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    java8如何通过Lambda处理List集合

    主要介绍了java8如何通过Lambda处理List集合,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java开发技术大全(500个源代码).

    useOnlyTest.java 创建多个对象,演示this的作用 useStaticBolck.java 使用静态块 useStVar.java 使用静态成员变量 第4章 示例描述:本章学习继承与多态。 absClass.java 抽象类定义示例 ancestor.java 基类...

    JList多选值的获取

    JList多选值的获取, 由JList组件实现的列表框有3种选取模式,设置方法为通过JList类的setSelectionMode(int selectionMode)方法,该方法的入口参数可以通过ListSelectionModel类中的静态常量设置。

    Java对象排序、中文排序、SortedSet排序使用和源码讲解

    但是通常排序算法不得不让程序员在写代码的过程中陷入对底层很多指针和位置的理解,java不希望这样,所以排序大多可以由java帮你做掉,例如,你要对一个数组排序,通过:Collections.sort(list)那么这个list被排序了...

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

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

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

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    多个对象列表排序

    不同类型对象组成的列表,根据某个属性或者多个属性进行排序

    Mybatis多参数查询与列表查询不同方式实现

    Mybatis多参数查询与列表查询不同方式实现,效果看博文 http://blog.csdn.net/evankaka/article/details/45671473

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包6

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包9

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包4

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

Global site tag (gtag.js) - Google Analytics