通过实体类中的某一个字段进行排序的两种方式

最近在开发项目的过程中,涉及到了用实体中的某一个字段进行排序,这里整理出来,留作备用。

我是新人,能力有限,今天又看到一个用起来更方便的方法,基于反射的,借鉴一下,同时推荐最后一种方式!


方式一:实体类实现Comparable接口的compareTo方法,简单明了

package cn.hustrc.pojo;
/**
 * 菜单的实体类,根据排序号对实体排序
 * <br>这里通过实现Comparable接口的compareTo方法
 * @author WangJY
 * @date 2017-1-14
 */
public class MenuIC implements Comparable<MenuIC>{
	/** 主键 */
	private String oid;
	/** 上級主键 */
	private String parentOid;
	/** 图标 */
	private String iconName;
	/** 链接 */
	private String hyperLink;
	/** 权限名称 */
	private String name;
	/** 等级 */
	private Integer level;
	/** 排序 */
	private Integer sort;

	public MenuIC() {
		super();
	}
	public MenuIC(String oid, String parentOid, String iconName,
			String hyperLink, String name, Integer level, Integer sort) {
		super();
		this.oid = oid;
		this.parentOid = parentOid;
		this.iconName = iconName;
		this.hyperLink = hyperLink;
		this.name = name;
		this.level = level;
		this.sort = sort;
	}
	public String getParentOid() {
		return parentOid;
	}
	public void setParentOid(String parentOid) {
		this.parentOid = parentOid;
	}
	public Integer getLevel() {
		return level;
	}
	public void setLevel(Integer level) {
		this.level = level;
	}
	public String getIconName() {
		return iconName;
	}
	public void setIconName(String iconName) {
		this.iconName = iconName;
	}
	public String getHyperLink() {
		return hyperLink;
	}
	public void setHyperLink(String hyperLink) {
		this.hyperLink = hyperLink;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getOid() {
		return oid;
	}
	public void setOid(String oid) {
		this.oid = oid;
	}
	public Integer getSort() {
		return sort;
	}
	public void setSort(Integer sort) {
		this.sort = sort;
	}
	@Override
	public String toString() {
		return "Menu [oid=" + oid + ", parentOid=" + parentOid + ", iconName="
				+ iconName + ", hyperLink=" + hyperLink + ", name=" + name
				+ ", level=" + level + ", sort=" + sort + "]";
	}

	@Override
	public int compareTo(MenuIC o) {
		return this.sort.compareTo(o.sort);
	}

}

package cn.hustrc.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import cn.hustrc.pojo.MenuIC;
import cn.hustrc.pojo.MenuNIC;
public class ComparableTest {
	@Test
	public void testComparablePojoBysort1() {
		MenuIC menu1 = new MenuIC("menu1_oid", "menu", "menu1_iconName",
				"menu1_hyperLink", "menu_name", 2, 1);
		MenuIC menu2 = new MenuIC("menu2_oid", "menu", "menu2_iconName",
				"menu2_hyperLink", "menu_name", 2, 2);
		MenuIC menu3 = new MenuIC("menu3_oid", "menu", "menu3_iconName",
				"menu3_hyperLink", "menu_name", 2, 3);
		MenuIC menu4 = new MenuIC("menu4_oid", "menu", "menu4_iconName",
				"menu4_hyperLink", "menu_name", 2, 4);
		List<MenuIC> list1 = new ArrayList<>();
		list1.add(menu2);
		list1.add(menu1);
		list1.add(menu4);
		list1.add(menu3);
		/*for (int i = 0 ;i < 1000000 ;i++) {
			list1.add(new MenuIC("menu4_oid", "menu", "menu4_iconName",
				"menu4_hyperLink", "menu_name", 2, i));
		}*/
		System.out
				.println("================MenuIC,通过实现Comparable接口实现按照sort排序前===================");
		for (MenuIC menu : list1) {
			System.out.println(menu);
		}
		long start = new Date().getTime();
		Collections.sort(list1);
		System.out.println(new Date().getTime() - start);

		System.out
				.println("================MenuIC,通过实现Comparable接口实现按照sort排序后===================");
		for (MenuIC menu : list1) {
			System.out.println(menu);
		}
		System.out.println("MenuIC,通过实现Comparable接口实现按照sort排序结束!");

	}
}
运行结果:
================MenuIC,通过实现Comparable接口实现按照sort排序前===================
Menu [oid=menu2_oid, parentOid=menu, iconName=menu2_iconName, hyperLink=menu2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menu1_oid, parentOid=menu, iconName=menu1_iconName, hyperLink=menu1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menu4_oid, parentOid=menu, iconName=menu4_iconName, hyperLink=menu4_hyperLink, name=menu_name, level=2, sort=4]
Menu [oid=menu3_oid, parentOid=menu, iconName=menu3_iconName, hyperLink=menu3_hyperLink, name=menu_name, level=2, sort=3]
0
================MenuIC,通过实现Comparable接口实现按照sort排序后===================
Menu [oid=menu1_oid, parentOid=menu, iconName=menu1_iconName, hyperLink=menu1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menu2_oid, parentOid=menu, iconName=menu2_iconName, hyperLink=menu2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menu3_oid, parentOid=menu, iconName=menu3_iconName, hyperLink=menu3_hyperLink, name=menu_name, level=2, sort=3]
Menu [oid=menu4_oid, parentOid=menu, iconName=menu4_iconName, hyperLink=menu4_hyperLink, name=menu_name, level=2, sort=4]


方式二:实体类正常书写,在真正的业务逻辑层时再做处理

package cn.hustrc.pojo;

/**
 * 菜单的实体类,根据排序号对实体排序
 * 
 * @author WangJY
 * @date 2017-1-14
 */
public class MenuNIC {

	/** 主键 */
	private String oid;
	/** 上級主键 */
	private String parentOid;
	/** 图标 */
	private String iconName;
	/** 链接 */
	private String hyperLink;
	/** 权限名称 */
	private String name;
	/** 等级 */
	private Integer level;
	/** 排序 */
	private Integer sort;

	public MenuNIC() {
		super();
	}

	public MenuNIC(String oid, String parentOid, String iconName,
			String hyperLink, String name, Integer level, Integer sort) {
		super();
		this.oid = oid;
		this.parentOid = parentOid;
		this.iconName = iconName;
		this.hyperLink = hyperLink;
		this.name = name;
		this.level = level;
		this.sort = sort;
	}
	public String getParentOid() {
		return parentOid;
	}
	public void setParentOid(String parentOid) {
		this.parentOid = parentOid;
	}
	public Integer getLevel() {
		return level;
	}
	public void setLevel(Integer level) {
		this.level = level;
	}
	public String getIconName() {
		return iconName;
	}
	public void setIconName(String iconName) {
		this.iconName = iconName;
	}
	public String getHyperLink() {
		return hyperLink;
	}
	public void setHyperLink(String hyperLink) {
		this.hyperLink = hyperLink;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getOid() {
		return oid;
	}
	public void setOid(String oid) {
		this.oid = oid;
	}
	public Integer getSort() {
		return sort;
	}
	public void setSort(Integer sort) {
		this.sort = sort;
	}
	@Override
	public String toString() {
		return "Menu [oid=" + oid + ", parentOid=" + parentOid + ", iconName="
				+ iconName + ", hyperLink=" + hyperLink + ", name=" + name
				+ ", level=" + level + ", sort=" + sort + "]";
	}

}
package cn.hustrc.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import cn.hustrc.pojo.MenuIC;
import cn.hustrc.pojo.MenuNIC;

public class ComparableTest {
	@Test
	public void testComparablePojoBysort2() {

		MenuNIC menuN1 = new MenuNIC("menuN1_oid", "menu", "menuN1_iconName",
				"menuN1_hyperLink", "menu_name", 2, 1);
		MenuNIC menuN2 = new MenuNIC("menuN2_oid", "menu", "menuN2_iconName",
				"menuN2_hyperLink", "menu_name", 2, 2);
		MenuNIC menuN3 = new MenuNIC("menuN3_oid", "menu", "menuN3_iconName",
				"menuN3_hyperLink", "menu_name", 2, 3);
		MenuNIC menuN4 = new MenuNIC("menuN4_oid", "menu", "menuN4_iconName",
				"menuN4_hyperLink", "menu_name", 2, 4);
		List<MenuNIC> list2 = new ArrayList<>();
		list2.add(menuN2);
		list2.add(menuN1);
		list2.add(menuN4);
		list2.add(menuN3);
		for (int i = 0 ;i < 1000000 ;i++) {
			list2.add(new MenuNIC("menu4_oid", "menu", "menu4_iconName",
				"menu4_hyperLink", "menu_name", 2, i));
		}
		/*System.out
				.println("================MenuNIC,不通过实现Comparable接口实现按照sort排序后===================");
		for (MenuNIC menuNIC : list2) {
			System.out.println(menuNIC);
		}*/
		long start = new Date().getTime();

		Collections.sort(list2, new Comparator<MenuNIC>() {
			@Override
			public int compare(MenuNIC o1, MenuNIC o2) {
				return o1.getSort().compareTo(o2.getSort());
			}
		});
		System.out.println(new Date().getTime() - start);

		/*System.out
				.println("================MenuNIC,不通过实现Comparable接口实现按照sort排序后===================");
		for (MenuNIC menuNIC : list2) {
			System.out.println(menuNIC);
		}*/

	}
}
运行结果:
================MenuNIC,不通过实现Comparable接口实现按照sort排序后===================
Menu [oid=menuN2_oid, parentOid=menu, iconName=menuN2_iconName, hyperLink=menuN2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menuN1_oid, parentOid=menu, iconName=menuN1_iconName, hyperLink=menuN1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menuN4_oid, parentOid=menu, iconName=menuN4_iconName, hyperLink=menuN4_hyperLink, name=menu_name, level=2, sort=4]
Menu [oid=menuN3_oid, parentOid=menu, iconName=menuN3_iconName, hyperLink=menuN3_hyperLink, name=menu_name, level=2, sort=3]
1
================MenuNIC,不通过实现Comparable接口实现按照sort排序后===================
Menu [oid=menuN1_oid, parentOid=menu, iconName=menuN1_iconName, hyperLink=menuN1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menuN2_oid, parentOid=menu, iconName=menuN2_iconName, hyperLink=menuN2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menuN3_oid, parentOid=menu, iconName=menuN3_iconName, hyperLink=menuN3_hyperLink, name=menu_name, level=2, sort=3]
Menu [oid=menuN4_oid, parentOid=menu, iconName=menuN4_iconName, hyperLink=menuN4_hyperLink, name=menu_name, level=2, sort=4]


方式一的好处就是代码整齐,易读性极强,但是排序字段在实体中写死,不容易根据其他字段进行排序。

方式二的好处就是可以任意根据某个字段进行排序并且不用在实体类中进行特别处理,但是代码不够整洁。

从执行的效率上来看,我最多用了 1000000 条数据进行比对,方式二的效率要高于方式一30%左右。


方式三:基于反射原理实现

package cn.hustrc.pojo;

/**
 * 菜单的实体类,根据排序号对实体排序
 * 
 * @author WangJY
 * @date 2017-1-14
 */
public class MenuNIC {

	/** 主键 */
	private String oid;
	/** 上級主键 */
	private String parentOid;
	/** 图标 */
	private String iconName;
	/** 链接 */
	private String hyperLink;
	/** 权限名称 */
	private String name;
	/** 等级 */
	private Integer level;
	/** 排序 */
	private Integer sort;

	public MenuNIC() {
		super();
	}

	public MenuNIC(String oid, String parentOid, String iconName,
			String hyperLink, String name, Integer level, Integer sort) {
		super();
		this.oid = oid;
		this.parentOid = parentOid;
		this.iconName = iconName;
		this.hyperLink = hyperLink;
		this.name = name;
		this.level = level;
		this.sort = sort;
	}

	public String getParentOid() {
		return parentOid;
	}

	public void setParentOid(String parentOid) {
		this.parentOid = parentOid;
	}

	public Integer getLevel() {
		return level;
	}

	public void setLevel(Integer level) {
		this.level = level;
	}

	public String getIconName() {
		return iconName;
	}

	public void setIconName(String iconName) {
		this.iconName = iconName;
	}

	public String getHyperLink() {
		return hyperLink;
	}

	public void setHyperLink(String hyperLink) {
		this.hyperLink = hyperLink;
	}

	public String getName() {
		return name;
	}

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

	public String getOid() {
		return oid;
	}

	public void setOid(String oid) {
		this.oid = oid;
	}

	public Integer getSort() {
		return sort;
	}

	public void setSort(Integer sort) {
		this.sort = sort;
	}

	@Override
	public String toString() {
		return "Menu [oid=" + oid + ", parentOid=" + parentOid + ", iconName="
				+ iconName + ", hyperLink=" + hyperLink + ", name=" + name
				+ ", level=" + level + ", sort=" + sort + "]";
	}

} 

package cn.hustrc.utils;

import java.lang.reflect.Method;
import java.util.Comparator;

/**
 * 根据实体类中的字段进行排序。 T代表实体类,propertyGetName是需要排序字段的get方法的方法名
 * 
 * @author WangJy
 * @date 2017-1-18
 * @param <T>
 */

public class SortListUtils<T> implements Comparator<T> {

	/**
	 * 排序字段的get方法名,如字段sort,对应的get方法为getSort(),这里就填getSort.
	 */
	private String propertyGetName;
	/** 排序规则--> 降序 */
	public static final String DESC = "DESC";
	/** 排序规则--> 升序 */
	public static final String ASC = "ASC";
	/**
	 * true 升序</br> flase 降序
	 * */
	private boolean isAsc;

	/**
	 * 根据字段的get方法的方法名进行排序
	 * @param propertyGetName
	 * </br>
	 *  排序字段的get方法名,如字段sort,对应的get方法为getSort(),这里就填getSort.
	 * @param sortType
	 * </br>
	 * 排序类型,
	 * </br>
	 * SortListUtils.DESC 降序</br>
	 * SortListUtils.ASC 升序
	 */
	public SortListUtils(String propertyGetName, String sortType) {
		this.propertyGetName = propertyGetName;
		if (SortListUtils.ASC.equals(sortType)) {
			this.isAsc = true;
		} else {
			this.isAsc = false;
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public int compare(T b1, T b2) {

		Class<?> clz = b1.getClass();
		Method mth = getPropertyMethod(clz, propertyGetName);

		try {
			Object o1 = mth.invoke(b1);
			Object o2 = mth.invoke(b2);

			if (o1 == null || o2 == null)
				return 0;
			Comparable value1 = (Comparable) o1;
			Comparable value2 = (Comparable) o2;

			if (isAsc) {
				return value1.compareTo(value2);
			} else {
				return value2.compareTo(value1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;

	}

	/**
	 * 获取方法
	 * @param clz
	 * 	</br> 实体对象
	 * @param propertyGetName
	 * </br> 方法名
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Method getPropertyMethod(Class clz, String propertyGetName) {
		Method mth = null;
		try {
			mth = clz.getMethod(propertyGetName);
		} catch (Exception e) {
			System.err.println("获取类名发生错误!");
		}
		return mth;
	}

	public String getPropertyGetName() {
		return propertyGetName;
	}

	public void setPropertyGetName(String propertyGetName) {
		this.propertyGetName = propertyGetName;
	}

	public boolean isAsc() {
		return isAsc;
	}

	public void setAsc(boolean isAsc) {
		this.isAsc = isAsc;
	}

}

package cn.hustrc.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import cn.hustrc.pojo.MenuNIC;
import cn.hustrc.utils.SortListUtils;

public class ComparableTest {

	@Test
	public void testComparablePojoBysort3() {


		MenuNIC menuN1 = new MenuNIC("menuN1_oid", "menu", "menuN1_iconName",
				"menuN1_hyperLink", "menu_name", 2, 1);
		MenuNIC menuN2 = new MenuNIC("menuN2_oid", "menu", "menuN2_iconName",
				"menuN2_hyperLink", "menu_name", 2, 2);
		MenuNIC menuN3 = new MenuNIC("menuN3_oid", "menu", "menuN3_iconName",
				"menuN3_hyperLink", "menu_name", 2, 3);
		MenuNIC menuN4 = new MenuNIC("menuN4_oid", "menu", "menuN4_iconName",
				"menuN4_hyperLink", "menu_name", 2, 4);
		List<MenuNIC> list3 = new ArrayList<>();
		list3.add(menuN2);
		list3.add(menuN1);
		list3.add(menuN4);
		list3.add(menuN3);
		/*for (int i = 0 ;i < 1000000 ;i++) {
			list3.add(new MenuNIC("menu4_oid", "menu", "menu4_iconName",
				"menu4_hyperLink", "menu_name", 2, i));
		}*/
		System.out
				.println("================MenuNIC,通过SortListUtils排序前===================");
		for (MenuNIC menuNIC : list3) {
			System.out.println(menuNIC);
		}
		long start = new Date().getTime();

		Collections.sort(list3, new SortListUtils<MenuNIC>("getSort",SortListUtils.ASC));
		System.out.println(new Date().getTime() - start);

		System.out
				.println("================MenuNIC,通过SortListUtils排序后===================");
		for (MenuNIC menuNIC : list3) {
			System.out.println(menuNIC);
		}

	}
}
运行结果:

================MenuNIC,通过SortListUtils排序前===================
Menu [oid=menuN2_oid, parentOid=menu, iconName=menuN2_iconName, hyperLink=menuN2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menuN1_oid, parentOid=menu, iconName=menuN1_iconName, hyperLink=menuN1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menuN4_oid, parentOid=menu, iconName=menuN4_iconName, hyperLink=menuN4_hyperLink, name=menu_name, level=2, sort=4]
Menu [oid=menuN3_oid, parentOid=menu, iconName=menuN3_iconName, hyperLink=menuN3_hyperLink, name=menu_name, level=2, sort=3]
1
================MenuNIC,通过SortListUtils排序后===================
Menu [oid=menuN1_oid, parentOid=menu, iconName=menuN1_iconName, hyperLink=menuN1_hyperLink, name=menu_name, level=2, sort=1]
Menu [oid=menuN2_oid, parentOid=menu, iconName=menuN2_iconName, hyperLink=menuN2_hyperLink, name=menu_name, level=2, sort=2]
Menu [oid=menuN3_oid, parentOid=menu, iconName=menuN3_iconName, hyperLink=menuN3_hyperLink, name=menu_name, level=2, sort=3]
Menu [oid=menuN4_oid, parentOid=menu, iconName=menuN4_iconName, hyperLink=menuN4_hyperLink, name=menu_name, level=2, sort=4]


最后的最后,我更加倾向于方式三,代码整洁,复用性强。

新人入门,能力有限,如有问题,欢迎指正!




  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值