当前位置: 首页 > 知识库问答 >
问题:

Java中多准则域的动态排序

王涵育
2023-03-14

我需要用一个动态搜索条件列表来排序一个动态对象列表。所以我有一个方法接受

sort(List<SortCriterion> sortCriteria, List<T> searchList){

}
 public class TradeOperator implements SearchResult{

      private String name;
      private String address;
      private String status;
      private Long   regNum;
      private Double price;
}
 public class SortCriterion{

       protected String field;   
       protected String direction;
    }
sort(List<SortCriterion> sortCriteria, List<T> searchList){
   Map<String, Set<String>> sortValues = new HashMap<>();
    populateSortedValues(sortCriteria, "ASC", sortValues);//group fields on ASC or DESC as key = ASC and Value = List of Fields
    populateSortedValues(sortCriteria, "DESC", sortValues);

    if (null != sortValues.get(Constants.ASC_ORDER))
    {
        for (String ascendingOrder : 
         sortValues.get(Constants.ASC_ORDER))
        {
        Collections.sort(list, new SearchResultComparator(ascendingOrder));
        }
    }

    if (null != sortValues.get(Constants.DESC_ORDER))
    {
        for (String descOrder : sortValues.get(Constants.DESC_ORDER))
        {
        Collections.sort(list, new 
               SearchResultComparator(descOrder).reversed());
        }
    }
}
public class SearchResultComparator implements Comparator<Object> {

private String getter;


public SearchResultComparator(String field) {
    this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);

}

@SuppressWarnings("unchecked")
public int compare(Object o1, Object o2) {
    try {
        if (o1 != null && o2 != null) {
            o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
            o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
            if(isDouble(o1.toString()) && isDouble(o2.toString())){
                Double d1 =  Double.parseDouble(o1.toString());
                Double d2 =  Double.parseDouble(o2.toString());
                return (d1 == null) ? -1 : ((d2 == null) ? 1 : ((Comparable<Double>) d1).compareTo(d2));
            }
        }
    } catch (Exception e) {
        throw new SystemException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
    }

        return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));


}

public boolean isDouble(String value)
{
try
{
    Double.parseDouble(value);
    return true;
}
catch (NumberFormatException e)
{
    return false;
}
}

}

它以一种方式排序。如果我在ASC中对一个字段进行排序,那么在DESC中对另一个字段进行排序,ASC排序将丢失。请帮忙。我刚到爪哇。

共有1个答案

权浩阔
2023-03-14

您不需要SearchResultComparator或分离ASC和DESC。使用此技术对任意顺序进行链式排序。

sort(List<SortCriterion> sortCriteria, List<T> list) {
    Collections.sort(list, new Comparator<T>() {
        public int compare(T one, T two) {
            CompareToBuilder compToBuild = new CompareToBuilder();
            sortCriteria.stream().forEachOrdered(sc -> {
                String fieldName = sc.getField();
                String direction = sc.getDirection();
                String fv1 = getFieldValue(fieldName, one);
                String fv2 = getFieldValue(fieldName, two);
                if(direction.equals("ASC")) {
                    compToBuild.append(fv1, fv2);
                }
                if(direction.equals("DESC")) {
                    compToBuild.append(fv2, fv1);
                }
            });
            return compToBuild.toComparison();
        }
    });
}

使用反射获取字段值

private String getFieldValue(String fieldName, T object) {
    Field field;
    try {
        field = object.getClass().getDeclaredField(fieldName);
    } catch (NoSuchFieldException e) {
        logger.error(e);
        return null;// or ""
    }
    field.setAccessible(true);
    try {
        return (String) field.get(object);
    } catch (IllegalAccessException e) {
        logger.error(e);
        return null;// or ""
    }
}
 类似资料:
  • 我需要创建一个“真正的”动态JPA。我得到一个语句。看起来像: 更新和解决方案得到了两个列表,第一个列表为和工作良好。第二个列表包含或语句,如exspected:

  • 我将与一起使用,并希望执行一些动态搜索。 player_team.java 对于每个域名,我都有这样的存储库:

  • 下一个示例比较器将对不包含任何双名的对象的其余集合进行排序: 第二个比较器正确地根据对象的年龄值对其进行排序,但它允许使用双重名称,我不明白这一点,因为外部的if-语句已经检查了两个对象的名称是否相等。为什么会这样?

  • 问题内容: 有人可以帮助我了解Java中的范围规则吗?这显然是无效的: 在内声明,在外部不可用。那么呢: 我对这里的语法错误感到惊讶。在外部作用域中声明,但以后将不可用。它是否通过某些特殊的循环规则绑定到内部块作用域?还有其他可能发生这种情况的情况吗? 问题答案: 想想for循环实际上是这样表示的:

  • 问题内容: 我有一个要根据下拉菜单中的值动态排序的对象数组。到目前为止,这是我的清单: 但是问题是排序可以是对象的属性,也可以是使用函数的计算值。它还应该能够以降序排序(可选)。 我知道我可以在orderBy后面使用字符串作为canByAnything变量,并传递对象的属性,例如: 我也知道我可以通过如下函数订购: 但是我不知道并且想要实现的是: 如何将其组合在一起,以便我可以结合对象的属性/属性

  • 有人能提供一个简单的例子来解释Java中动态多态性和静态多态性之间的区别吗?