以下方法执行排序。
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
类型的字段。
由于还有其他几个具有相同字段和相同数据类型的类,因此我希望此方法是通用的,因此只需像这样定义一次,
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;
}
但是这样做的话,像List<Entity>
这样的表达式将不会被编译,因为通用类型参数T::getId
的结果为T
。
有没有一种方法可以在不知道实际类类型的情况下进行代码排序,从而可以防止在需要时在任何地方重复使用此方法?
参考方案
一种简单的方法(不必依靠反射魔术)是为具有与Entity
相同的数据类型的相同字段的所有类型引入一个公共接口。
考虑以下IdSize
接口和以下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语句进行了一些重构,以删除重复的代码。)另外,您可能想添加一个默认子句。
Diamond运算符(<>)在Java 1.7中不起作用 - java编译jsp文件时出现以下错误: 低于1.7的源级别不允许使用''运算符我正在使用jdk 1.7.x和eclipse Kepler另外我已经在Eclipse的项目首选项中设置了1.7 as compliance level,但是代码仍然无法正常工作我应该添加其他配置吗? 参考方案 检查Eclipse中的以下区域:Right Click Project >…
在Java Swing中输入JButton的键焦点? - java如何在Java Swing中使JButton的Enter键成为焦点?我已经这样做了btn_Login.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("enter key pre…
无法从ArrayList <String>转换为List <Comparable> - java当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…
合并List <T>和List <Optional <T >> - java鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…
实例化类型<?>的泛型类 - java我正在为SCJP / OCPJP学习,并且遇到了一个对我来说很奇怪的示例问题。该示例代码实例化了两个通用集合:List<?> list = new ArrayList<?>(); List<? extends Object> list2 = new ArrayList<? extends Object>(); …