需求:由于某方便的需求,需要根据对象的属性排序,就从网上找了好多资料、整理、封装,可以实现对象属性的排序,对象的属性类型可以是字符串、整形、时间类型、包装类;直接上代码,代码中都有信息的注释,不再赘述。
1.主要的实现类SortListObjectAttr
package com.anzhonghui.zawsze.pojo;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.Date;
import com.anzhonghui.zawsze.util.CommonUtil;
/**
*
* @ClassName: SortListObjectAttr.java
* @Description: 根据指定的属性名排序包装类集合
*
* @version: v1.0.0
* @author: 安仲辉
* @date: 2018年5月5日 下午9:02:13
*
* Modification History:
* Date Author Version Description
*---------------------------------------------------------*
* 2018年5月5日 安仲辉 v1.0.0 修改原因
*/
public class SortListObjectAttr<T> implements Comparator<T> {
//1.属性名称
private String propertyName;
//2.是否升序
private boolean isAsc;
//3.是否是包装类的属性
private Boolean isObjectAttr;
//用于包装类普通字段的比较
public SortListObjectAttr(String propertyname, boolean isasc) {
this.propertyName = propertyname;
this.isAsc = isasc;
}
//用于包装类中含包装类的比较
public SortListObjectAttr(String propertyname, boolean isasc, Boolean isObjectAttr) {
this.propertyName = propertyname;
this.isAsc = isasc;
this.isObjectAttr = isObjectAttr;
}
/**
*
* @Function: SortListObjectAttr.java
* @Description: 重写的排序方法
*
* @param:比较的对象
* @return:返回比较大小的结果
*
* @version: v1.0.0
* @author: 安仲辉
* @date: 2018年5月5日 下午9:00:38
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public int compare(T b1, T b2) {
Class<?> clz = b1.getClass();//获取对象的类
Object o1 = null;
Object o2 = null;
Method mth = null;
if(isObjectAttr == null){
mth = getPropertyMethod(clz, propertyName);//根据类和属性名,获取完整的get方法
try {
o1 = mth.invoke(b1);//根据定方法名获取的值(从对象中获取要排序属性的值)
o2 = mth.invoke(b2);
} catch (Exception e) {
e.printStackTrace();
}
} else {
if (!isObjectAttr) {
mth = getPropertyMethod(clz, propertyName);
try {
o1 = mth.invoke(b1);
o2 = mth.invoke(b2);
} catch (Exception e) {
e.printStackTrace();
}
} else {
//类中包装类操作
try {
String[] split = propertyName.split("[.]");
Method mthTemp = getPropertyMethod(clz, split[0]);
Class<?> clz2 = mthTemp.getReturnType();//获取类中的包装类类型
mth = getPropertyMethod(clz2, split[1]);//获取包装类中指定的属性
if(mthTemp.invoke(b1) != null){
o1 = mth.invoke(mthTemp.invoke(b1));//先从排序类中获取包装类,再从包装类中获取值
}
if(mthTemp.invoke(b2) != null){
o2 = mth.invoke(mthTemp.invoke(b2));
}
} catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
System.out.println("请检查参数:方法名、是否是包装类的方法 是否正确");
arrayIndexOutOfBoundsException.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (o1 == null && o2 == null)
return 0;
if (o1 == null && o2 != null) {//如果是空值,根据类型获取默认值,避免因null影响排序
o1 = getDefaultValue(mth.getReturnType());
} else if (o1 != null && o2 == null) {
o2 = getDefaultValue(mth.getReturnType());
}
Comparable value1 = (Comparable) o1;
Comparable value2 = (Comparable) o2;
if (isAsc) {//升序
return value1.compareTo(value2);
} else {
return value2.compareTo(value1);
}
}
/**
*
* @Function: SortList.java
* @Description: 获取方法
*
* @param: clz 查询的类; propertyName 查询的属性名
* @return: 根据属性名从类中查询到的get方法 example:getAge
*
* @version: v1.0.0
* @author: 安仲辉
* @date: 2018年5月5日 下午6:25:29
*
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Method getPropertyMethod(Class clz, String propertyName) {
Method mth = null;
try {
mth = clz.getMethod("get" + CommonUtil.upperCase(propertyName));
} catch (Exception e) {
System.out.println("获取方法发生错误!");
e.printStackTrace();
}
return mth;
}
/**
*
* @Function: SortList.java
* @Description: 根据类型获取默认值(为了方便空值的排序)
*
* @param: 类型
* @return:返回默认值
*
* @version: v1.0.0
* @author: 安仲辉
* @date: 2018年5月5日 下午6:31:07
*
*/
public static Object getDefaultValue(Class<?> type){
if (type == String.class) {
return "";
} else if (type == Integer.class) {
return 0;
} else if (type == Date.class){
return new Date(0);
} else if (type == Timestamp.class) {
return new Timestamp(0);
}
return null;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public boolean isAsc() {
return isAsc;
}
public void setAsc(boolean isAsc) {
this.isAsc = isAsc;
}
public boolean isObjectAttr() {
return isObjectAttr;
}
public void setObjectAttr(boolean isObjectAttr) {
this.isObjectAttr = isObjectAttr;
}
}
2.工具类,CommonUtil
package
com
.
anzhonghui
.
zawsze
.
util
;
/**
*
*
@ClassName
: CommonUtil.java
*
@Description
: 一些常用的工具类方法
*
*
@version
: v1.0.0
*
@author
: AN
*
@date
: 2018年5月5日 下午9:06:46
*
* Modification History:
* Date Author Version Description
*
---------------------------------------------------------
*
* 2018年5月5日 安仲辉 v1.0.0 修改原因
*/
public
class
CommonUtil
{
/**
*
*
@Function
: SortList.java
*
@Description
: 首字母大写
*
*
@param
:需要首字母大写的字符串
*
@return
:首字母大写后的字符串
*
*
@version
: v1.0.0
*
@author
: 安仲辉
*
@date
: 2018年5月5日 下午6:24:09
*
*/
public
static
String
upperCase(
String
str
)
{
char
[]
ch
=
str
.
toCharArray
()
;
if
(
ch
[
0
]
>=
'a'
&&
ch
[
0
]
<=
'z'
)
{
ch
[
0
]
=
(
char
)
(
ch
[
0
]
-
32
)
;
}
return
new
String
(
ch
)
;
}
}
3.MyTest测试类、User测试排序的类,Father是User的某个属性类
## 测试
package
com
.
anzhonghui
.
zawsze
.
test
;
import
java
.
sql
.
Timestamp
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Collections
;
import
java
.
util
.
List
;
import
org
.
junit
.
Test
;
import
com
.
anzhonghui
.
zawsze
.
pojo
.
SortListObjectAttr
;
public
class
MyTest
{
@Test
public
void
fun1(){
//1.根据用户的用户名,降序排序
List
<
User
>
lists
=
new
ArrayList
<>
()
;
User
user
=
new
User
(
"an"
,
10
,
new
Timestamp
(
System
.
currentTimeMillis
()))
;
User
user2
=
new
User
(
"cc"
,
null
,
new
Timestamp
(
System
.
currentTimeMillis
()
-
1000
*
60
*
60
))
;
User
user3
=
new
User
(
"bb"
,
12
,
null
)
;
User
user4
=
new
User
(
null
,
15
,
new
Timestamp
(
System
.
currentTimeMillis
()
-
1000
*
60
*
60
*
2
))
;
lists
.
add
(
user
)
;
lists
.
add
(
user2
)
;
lists
.
add
(
user3
)
;
lists
.
add
(
user4
)
;
System
.
out
.
println
(
"排序前的内容:"
)
;
for
(
User
us
:
lists
)
{
System
.
out
.
println
(
us
.
toString
())
;
}
Collections
.
sort
(
lists
,
new
SortListObjectAttr
<
User
>
(
"name"
,
false
))
;
System
.
out
.
println
(
"排序后的内容:"
)
;
for
(
User
us
:
lists
)
{
System
.
out
.
println
(
us
.
toString
())
;
}
//根据用户对象的father属性的name属性排序
List
<
User
>
lists2
=
new
ArrayList
<>
()
;
User
user5
=
new
User
(
"an"
,
10
,
new
Timestamp
(
System
.
currentTimeMillis
())
,
new
Father
(
"33"
))
;
User
user6
=
new
User
(
"bb"
,
null
,
new
Timestamp
(
System
.
currentTimeMillis
()
-
1000
*
60
*
60
))
;
User
user7
=
new
User
(
"cc"
,
12
,
null
,
new
Father
(
"22"
))
;
User
user8
=
new
User
(
null
,
15
,
new
Timestamp
(
System
.
currentTimeMillis
()
-
1000
*
60
*
60
*
2
)
,
new
Father
(
"11"
))
;
lists2
.
add
(
user5
)
;
lists2
.
add
(
user6
)
;
lists2
.
add
(
user7
)
;
lists2
.
add
(
user8
)
;
System
.
out
.
println
(
"包装类的排序前的内容:"
)
;
for
(
User
us
:
lists2
)
{
System
.
out
.
println
(
us
.
toString
())
;
}
Collections
.
sort
(
lists2
,
new
SortListObjectAttr
<
User
>
(
"father.name"
,
true
,
true
))
;
System
.
out
.
println
(
"包装类的排序后的内容:"
)
;
for
(
User
us
:
lists2
)
{
System
.
out
.
println
(
us
.
toString
())
;
}
}
}
## 测试
package
com
.
anzhonghui
.
zawsze
.
test
;
import
java
.
sql
.
Timestamp
;
public
class
User
{
private
String
name
;
private
Integer
age
;
private
Timestamp
birth
;
private
Father
father
;
public
User(
String
name
,
Integer
age
,
Timestamp
birth
)
{
super
()
;
this
.
name
=
name
;
this
.
age
=
age
;
this
.
birth
=
birth
;
}
public
User(
String
name
,
Integer
age
,
Timestamp
birth
,
Father
father
)
{
super
()
;
this
.
name
=
name
;
this
.
age
=
age
;
this
.
birth
=
birth
;
this
.
father
=
father
;
}
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
Timestamp
getBirth()
{
return
birth
;
}
public
void
setBirth(
Timestamp
birth
)
{
this
.
birth
=
birth
;
}
public
Father
getFather()
{
return
father
;
}
public
void
setFather(
Father
father
)
{
this
.
father
=
father
;
}
@Override
public
String
toString()
{
return
"User [name="
+
name
+
", age="
+
age
+
", birth="
+
birth
+
", father="
+
father
+
"]"
;
}
}
## 测试
package
com
.
anzhonghui
.
zawsze
.
test
;
public
class
Father
{
private
String
name
;
public
String
getName()
{
return
name
;
}
public
void
setName(
String
name
)
{
this
.
name
=
name
;
}
public
Father
(
String
name
)
{
super
()
;
this
.
name
=
name
;
}
@Override
public
String
toString()
{
return
"Father [name="
+
name
+
"]"
;
}
}
4.测试结果
排序前的内容:对User的name属性进行降序排序
User [name=an, age=10, birth=2018-05-09 11:31:21.309, father=null]
User [name=cc, age=null, birth=2018-05-09 10:31:21.309, father=null]
User [name=bb, age=12, birth=null, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.309, father=null]
排序后的内容:
User [name=cc, age=null, birth=2018-05-09 10:31:21.309, father=null]
User [name=bb, age=12, birth=null, father=null]
User [name=an, age=10, birth=2018-05-09 11:31:21.309, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.309, father=null]
包装类的排序前的内容:对father属性的name属性进行升序排序
User [name=an, age=10, birth=2018-05-09 11:31:21.322, father=Father [name=33]]
User [name=bb, age=null, birth=2018-05-09 10:31:21.322, father=null]
User [name=cc, age=12, birth=null, father=Father [name=22]]
User [name=null, age=15, birth=2018-05-09 09:31:21.322, father=Father [name=11]]
包装类的排序后的内容:
User [name=bb, age=null, birth=2018-05-09 10:31:21.322, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.322, father=Father [name=11]]
User [name=cc, age=12, birth=null, father=Father [name=22]]
User [name=an, age=10, birth=2018-05-09 11:31:21.322, father=Father [name=33]]
5.可以直接用这个jar包
https://download.csdn.net/download/qq_35398517/10402728