mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-06 05:38:00 +08:00
新增多个字段比较器
This commit is contained in:
parent
6bdede538c
commit
c10c6f06aa
@ -0,0 +1,60 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Bean字段排序器<br>
|
||||
* 参阅feilong-core中的PropertyComparator
|
||||
*
|
||||
* @param <T> 被比较的Bean
|
||||
* @author Looly
|
||||
*/
|
||||
public abstract class BaseFieldComparator<T> implements Comparator<T>, Serializable {
|
||||
private static final long serialVersionUID = -3482464782340308755L;
|
||||
|
||||
/**
|
||||
* 比较器方法
|
||||
*
|
||||
* @param o1 对象1
|
||||
* @param o2 对象2
|
||||
* @return -1 0 1
|
||||
*/
|
||||
@Override
|
||||
public abstract int compare(T o1, T o2);
|
||||
|
||||
protected int compareItem(T o1, T o2, Field field) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
} else if (null == o1) {// null 排在后面
|
||||
return 1;
|
||||
} else if (null == o2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Comparable<?> v1;
|
||||
Comparable<?> v2;
|
||||
try {
|
||||
v1 = (Comparable<?>) ReflectUtil.getFieldValue(o1, field);
|
||||
v2 = (Comparable<?>) ReflectUtil.getFieldValue(o2, field);
|
||||
} catch (Exception e) {
|
||||
throw new ComparatorException(e);
|
||||
}
|
||||
|
||||
return compare(o1, o2, v1, v2);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private int compare(T o1, T o2, Comparable fieldValue1, Comparable fieldValue2) {
|
||||
int result = ObjectUtil.compare(fieldValue1, fieldValue2);
|
||||
if (0 == result) {
|
||||
//避免TreeSet / TreeMap 过滤掉排序字段相同但是对象不相同的情况
|
||||
result = CompareUtil.compare(o1, o2, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,23 +1,18 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Bean字段排序器<br>
|
||||
* 参阅feilong-core中的PropertyComparator
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
* @param <T> 被比较的Bean
|
||||
* @author Looly
|
||||
*/
|
||||
public class FieldComparator<T> implements Comparator<T>, Serializable {
|
||||
public class FieldComparator<T> extends BaseFieldComparator<T> {
|
||||
private static final long serialVersionUID = 9157326766723846313L;
|
||||
|
||||
private final Field field;
|
||||
@ -30,40 +25,13 @@ public class FieldComparator<T> implements Comparator<T>, Serializable {
|
||||
*/
|
||||
public FieldComparator(Class<T> beanClass, String fieldName) {
|
||||
this.field = ClassUtil.getDeclaredField(beanClass, fieldName);
|
||||
if(this.field == null){
|
||||
if (this.field == null) {
|
||||
throw new IllegalArgumentException(StrUtil.format("Field [{}] not found in Class [{}]", fieldName, beanClass.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
if (o1 == o2) {
|
||||
return 0;
|
||||
} else if (null == o1) {// null 排在后面
|
||||
return 1;
|
||||
} else if (null == o2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Comparable<?> v1;
|
||||
Comparable<?> v2;
|
||||
try {
|
||||
v1 = (Comparable<?>) ReflectUtil.getFieldValue(o1, this.field);
|
||||
v2 = (Comparable<?>) ReflectUtil.getFieldValue(o2, this.field);
|
||||
} catch (Exception e) {
|
||||
throw new ComparatorException(e);
|
||||
}
|
||||
|
||||
return compare(o1, o2, v1, v2);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private int compare(T o1, T o2, Comparable fieldValue1, Comparable fieldValue2) {
|
||||
int result = ObjectUtil.compare(fieldValue1, fieldValue2);
|
||||
if(0 == result) {
|
||||
//避免TreeSet / TreeMap 过滤掉排序字段相同但是对象不相同的情况
|
||||
result = CompareUtil.compare(o1, o2, true);
|
||||
}
|
||||
return result;
|
||||
return compareItem(o1, o2, this.field);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package cn.hutool.core.comparator;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Bean字段排序器<br>
|
||||
* 参阅feilong-core中的PropertyComparator
|
||||
*
|
||||
* @param <T> 被比较的Bean
|
||||
* @author Looly
|
||||
*/
|
||||
public class FieldsComparator<T> extends BaseFieldComparator<T> {
|
||||
private static final long serialVersionUID = 8649196282886500803L;
|
||||
|
||||
private final Field[] fields;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param beanClass Bean类
|
||||
* @param fieldNames 多个字段名
|
||||
*/
|
||||
public FieldsComparator(Class<T> beanClass, String... fieldNames) {
|
||||
this.fields = new Field[fieldNames.length];
|
||||
for (int i = 0; i < fieldNames.length; i++) {
|
||||
this.fields[i] = ClassUtil.getDeclaredField(beanClass, fieldNames[i]);
|
||||
if (this.fields[i] == null) {
|
||||
throw new IllegalArgumentException(StrUtil.format("Field [{}] not found in Class [{}]", fieldNames[i], beanClass.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
for (Field field : fields) {
|
||||
int compare = this.compareItem(o1, o2, field);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user