Java :: Использование обобщений для создания экземпляра мультикомпаратора "во время выполнения" - PullRequest
0 голосов
/ 29 сентября 2019

У меня есть класс MultiComparator, который позволяет объединять несколько сортировок. Например, приведенный ниже код создает сортировку для контактов.

// This works
contactList.sort(
    new MultiComparator<>(
      new ContactComparator(ContactComparator.Sort.CONTACT_NAME),
      new ContactComparator(ContactComparator.Sort.ID)
    )
);

Однако мне нужно создать порядок сортировки на лету во время выполнения, и у меня возникают проблемы с выяснением, как это сделать, поскольку компилятор Java продолжает выдавать мне ошибку: «Невозможно определить аргументы(невозможно разрешить конструктор) ". Для простоты я опустил логику, которая создала бы «упорядоченный» список полей сортировки, но предположил, что пользователь мог создать порядок. Моя проблема становится, как создать MultiComparator, учитывая этот упорядоченный список. Есть идеи?

List<ContactComparator> orderedContactComparators = new ArrayList();   // assume this was created above
contactList.sort(
    // compiler error: "Cannot infer arguments (unable to resolve constructor)
    new MultiComparator<>(orderedContactComparators)
);

Для справки ниже приведены другие классы ...

Класс ContactComparator

public class ContactComparator implements Comparator<Contact> {

    private Sort currentSort;
    private boolean sortAsc;

    public enum Sort {
        NAME, ADDRESS, ID
    }

    public ContactComparator() {
        currentSort = Sort.NAME;
        sortAsc = true;
    }

    public ContactComparator(Sort sort) {
        currentSort = Objects.requireNonNullElse(sort, Sort.NAME);
        sortAsc = true;
    }

    @Override
    public int compare(Contact o1, Contact o2){
        // Compare logic here
    }

}

Класс MultiComparator

public class MultiComparator<T> implements Comparator<T> {

    private List<Comparator<? super T>> comparators;

    public MultiComparator(List<Comparator<? super T>> comparators) {
        this.comparators = comparators;
    }

    @SafeVarargs
    public MultiComparator(Comparator<? super T>... comparators) {
        this(Arrays.asList(comparators));
    }

    public int compare(T o1, T o2) {
        for (Comparator<? super T> c : comparators) {
            int result = c.compare(o1, o2);
            if (result != 0) {
                return result;
            }
        }
        return ObjectUtils.compare(o1.hashCode(), o2.hashCode());
    }

    @SafeVarargs
    public static <T> void sort(List<T> list, Comparator<? super T>... comparators) {
        list.sort(new MultiComparator<T>(comparators));
    }
}
...