以下方法执行排序。
public List<Comparator<Entity>> sort(Map<String, String> map) {
List<Comparator<Entity>> list = new ArrayList<Comparator<Entity>>();
for (Map.Entry<String, String> entry : map.entrySet()) {
boolean sortOrder = entry.getValue().equalsIgnoreCase("asc");
switch (entry.getKey()) {
case "id":
list.add(sortOrder ? Comparator.comparing(Entity::getId) : Comparator.comparing(Entity::getId, Comparator.reverseOrder()));
break;
case "size":
list.add(sortOrder ? Comparator.comparing(Entity::getSize) : Comparator.comparing(Entity::getSize, Comparator.reverseOrder()));
//break;
}
}
return list;
}
上述方法返回的列表按以下方式使用。
// map is initialized somewhere based on client's interactions with sorting.
// Based on client's interactions, map may be empty or it may contain one or more ordering fields.
if (MapUtils.isNotEmpty(map)) { // map = new LinkedHashMap<String, String>();
List<Comparator<Entity>> comparators = sort(map);
Comparator<Entity> comparator = comparators.remove(0);
for (Comparator<Entity> c : comparators) {
comparator = comparator.thenComparing(c);
}
list = list.stream().sorted(comparator).collect(Collectors.toList());
} else {
// This is the default ordering.
list = list.stream().sorted(Comparator.comparing(Entity::getId).reversed()).collect(Collectors.toList());
}
Entity
包含两个名为 id
的字段类型 Integer
和size
类型 BigDecimal
和list
是 List<Entity>
的一种类型.
由于还有其他几个类具有相同的字段和相同的数据类型,因此我希望此方法是通用的,因此只需像这样定义一次,
public <T extends Object> List<Comparator<T>> sort(Map<String, String> map, Class<T> clazz) {
List<Comparator<T>> list = new ArrayList<Comparator<T>>();
// Sorting logic.
return list;
}
但是这样做的话,像 T::getId
这样的表达式不会编译得那么明显,因为泛型类型参数 T
计算结果为Object
.
有没有一种方法可以在不知道实际类类型的情况下编写排序代码,以便在需要时可以防止该方法在任何地方重复?
最佳答案
一种无需依赖反射魔法的简单方法是为所有具有与 Entity
相同字段和相同数据类型的类型引入一个通用接口(interface)。
考虑以下 IdSize
接口(interface)和以下 Entity
。
interface IdSize {
Integer getId();
BigDecimal getSize();
}
class Entity implements IdSize {
private Integer id;
private BigDecimal size;
@Override
public Integer getId() {
return id;
}
@Override
public BigDecimal getSize() {
return size;
}
}
然后你可以使你的方法像这样通用:
public <T extends IdSize> List<Comparator<T>> sort(Map<String, String> map) {
List<Comparator<T>> list = new ArrayList<Comparator<T>>();
for (Map.Entry<String, String> entry : map.entrySet()) {
boolean sortOrder = entry.getValue().equalsIgnoreCase("asc");
Comparator<T> comparator = null;
switch (entry.getKey()) {
case "id":
comparator = Comparator.comparing(IdSize::getId);
break;
case "size":
comparator = Comparator.comparing(IdSize::getSize);
break;
default: // do something here, throw an exception?
}
list.add(sortOrder ? comparator : comparator.reversed());
}
return list;
}
(我重构了一点 switch-case 语句以删除重复的代码。)。另外,您可能想要添加默认子句。
关于java - 使用 Java 8 中的泛型方法对集合进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33084560/