Динамическая сортировка с несколькими полями Критерии в Java - PullRequest
0 голосов
/ 07 мая 2019

Мне нужно отсортировать список динамических объектов со списком критериев динамического поиска.Итак, у меня есть метод, который принимает

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

}

Теперь, если у меня есть список объектов TradeOperator, который выглядит следующим образом.Я могу отправить другой объект, например, CarOperator, в методе сортировки.

 public class TradeOperator implements SearchResult{

      private String name;
      private String address;
      private String status;
      private Long   regNum;
      private Double price;
}

Код SortCriterion выглядит следующим образом.

 public class SortCriterion{

       protected String field;   
       protected String direction;
    }

, где поле может быть TradeOperator.name и direction = ASC или DESC.Теперь я могу передать список SortCriterion с несколькими полями и направлениями.

Вот что я сделал.Я собрал все поля, которые являются ASC, и все поля, которые являются DESC, в MAP sortValues ​​с Key = ASC и DESC, а значения являются списком полей.Затем сортируйте его в ASC, а затем в обратном порядке.

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

Вот класс SearchResultComparator.

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.Пожалуйста помоги.Я новичок в Java.

1 Ответ

0 голосов
/ 11 мая 2019

Вам не нужен 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 ""
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...