Компаратору Java дали имя свойства для сравнения - PullRequest
4 голосов
/ 09 ноября 2010

Моя проблема в этом;Я должен заказать таблицу данных.Каждая строка таблицы является объектом (назовем его TableObject), хранящимся в списке.Каждый столбец данных является свойством класса (обычно это String).

Я должен выполнить обычное упорядочение данных, когда пользователь нажимает на любой столбец.Поэтому я подумал об изменении списка на TreeSet и реализации Comparator в моем TableObject.

Проблема возникает, когда я пытаюсь изменить порядок TreeSet.Сначала сравнение довольно просто (проверка исключений в parseInt опущена):

   public int compare(TableObject to1, TableObject to2){
        TableObject t1 = to1;
        TableObject t2 = to2;

        int result = 1;

        if(Integer.parseInt(t1.getId()) == Integer.parseInt(t2.getId())){result=0;}
        if(Integer.parseInt(t1.getId()) < Integer.parseInt(t2.getId())){result=-1;}

        return result;

    }

Но когда мне нужно переупорядочить текст данных или другие десятки данных, которые у TableObject естьиметь проблему.Я не хочу создавать десятки функций сравнения, каждая для одной.Я предпочитаю не использовать переключатель (или цепочку ifs), чтобы решить, как сравнивать объект.

Есть ли способ сделать это каким-то образом (например, Reflexive), это не означает, чтонапишет как сотни строк почти одного и того же кода?

Спасибо за все!

Ответы [ 3 ]

5 голосов
/ 09 ноября 2010

Компонент Bean должен работать.

3 голосов
/ 09 ноября 2010

Что вы можете сделать, это заставить компаратор принять String, представляющий имя параметра для сортировки в его конструкторе.

Затем вы можете использовать отражение для сортировки по данному параметру.

Следующий код очень грязный.Но я думаю, что это иллюстрирует суть того, что вам нужно сделать.

public class FieldComparator<T> implements Comparator<T> {
    String fieldName;

    public FieldComparator(String fieldName){
        this.fieldName = fieldName;
    }

    @Override
    public int compare(T o1, T o2) {
        Field toCompare = o1.getClass().getField(fieldName);
        Object v1 = toCompare.get(o1);
        Object v2 = toCompare.get(o2);
        if (v1 instanceof Comparable<?> && v2 instanceof Comparable<?>){
            Comparable c1 = (Comparable)v1;
            Comparable c2 = (Comparable)v2;
            return c1.compareTo(c2);
        }else{
            throw new Exception("Counld not compare by field");
        }
    }
}
1 голос
/ 09 ноября 2010

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

См. Field класс и особенно метод Field.get.

(хотя я бы не рекомендовал это делать, поскольку рефлексия не предназначена для задач такого типа.)

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