新增多个字段比较器

This commit is contained in:
bwcx_jzy 2021-07-19 16:35:33 +08:00
parent 6bdede538c
commit c10c6f06aa
3 changed files with 116 additions and 38 deletions

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}