Как вытащить отражение из этого цикла? - PullRequest
2 голосов
/ 17 января 2012

Как вытащить отражение из этого цикла и передать метод получения, если это возможно.

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list){
        Collections.sort(list, new Comparator<E>() {
                public int compare(E o1, E o2) {
                    return compareFields(o1,o2,fieldName.replace("SortBy", "get"),sortAsc);
                }
            }
        );
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected <E> int compareFields(E o1, E o2,String fieldName, boolean sortAsc){
        try { 
            Comparable o1Data;
            Comparable o2Data;
            o1Data = (Comparable) o1.getClass().getMethod(fieldName).invoke(o1);
            o2Data = (Comparable) o2.getClass().getMethod(fieldName).invoke(o2);
            if(o1Data == null && o2Data == null){
                return 0;
            } else if (o1Data == null){
                return 1;
            } else if (o2Data == null){
                return -1;
            }
            int result = o2Data.compareTo(o1Data); 
            return (sortAsc) ? -result : result ; 
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

Контекст: у меня есть много экранов с таблицами данных.Каждый из них построен из списка.Каждая таблица данных должна сортироваться по каждому из 6 столбцов.Столбцы имеют дату или строку.

Ответы [ 3 ]

2 голосов
/ 17 января 2012

Если вы можете предположить, что все элементы одного типа.

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list) throws NoSuchMethodException {
    final Method f = list.get(0).getClass().getMethod(fieldName.replace("SortBy", "get"));
    f.setAccessible(true);
    final int direction = sortAsc ? +1 : -1;
    Collections.sort(list, new Comparator<E>() {
        public int compare(E o1, E o2) {
            return compareFields(o1, o2, f, direction);
        }
    }
    );
}

@SuppressWarnings({"rawtypes", "unchecked"})
protected <E> int compareFields(E o1, E o2, Method getter, int sortAsc) {
    try {
        Comparable o1Data = (Comparable) getter.invoke(o1);
        Comparable o2Data = (Comparable) getter.invoke(o2);
        if (o1Data == null)
            return o2Data == null ? 0 : 1;
        if (o2Data == null)
            return -1;
        return sortAsc * o2Data.compareTo(o1Data);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
2 голосов
/ 17 января 2012

У объектов данных должен быть реализован интерфейс, который включает метод getFieldByName.

1 голос
/ 17 января 2012

Apache Bean Utils весьма полезны для такого рода вещей. Скорее всего, они используют отражение внутри, но это означает, что вам не нужно, и вы можете иметь хороший чистый код:

...

Comparable o1Data = (Comparable) PropertyUtils.getProperty(o1, fieldName);
Comparable o2Data = (Comparable) PropertyUtils.getProperty(o2, fieldName);
if(o1Data == null && o2Data == null) {

...

Здесь fieldName должно быть именем свойства / поля, а не получателем. Поскольку переменная в вашем коде содержит имя получателя, вы, вероятно, должны вместо этого назвать его как getterName.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...