• ,

level26.lesson02.task03

Решил, проблема была в аргументе.
Для таких же, как я, подскажу: в конструктор нужно не List передавать.

58 комментариев

IgorChaiun
  • IgorChaiun
  • +1
  • Комментарий отредактирован 2014-05-22 16:19:16 пользователем IgorChaiun
Помогите разобраться с условием, не могу понять. Просят написать компаратор, компаратор как я себе его представляю класс который реализует интерфейс Comparator, там есть метод compare который возвращает результат сравнения объектов по нужным параметрам.
Во втором пункте просят сортировать данные, так вот я не могу понять нам требуется сортировать данные или просто реализовать интерфейс компаратор в нашем классе.

Если сортировать, то я совсем не понимаю как это реализовать в классе компаратор.
Если реализовать метод compare, то как сравнивать объекты с помощью нескольких компараторов, какой смысл от этого, последовательно что ли применять компараторы к двум объектам

Или нам нужно определить какой из компараторов подходит по типу к сортируемым объектам и по нему отсортировать.

В общем кто сделал, дайте пожалуйста подсказку
provisota
  • provisota
  • +1
  • Комментарий отредактирован 2014-06-01 13:56:08 пользователем provisota
такс, даю биг хинт)
алгоритм сравнения таков:
1) У нас имеется один или несколько компараторов (которые передаются в конструктор нашего мультикомпараторского класса CustomizedComparator =) допустим нам их передали аж три.
2) Внутри метода compare() перебираем в цикле переданные нам компараторы в той последовательности в которой они были нам переданы.
3) Внутри цикла сравниваем переданные в метод compare() (класса CustomizedComparator) объекты (T o1 и T o2) методом compare() первого из переданных компараторов.
4) Если результат сравнения != 0 (т.е. объекты различаются по критерию (колонке) первого из компараторов) то возвращаем результат их сравнения, и выходим тем самым из цикла и из метода. (остальные переданные компараторы нас в таком случае уже не интересуют!!! =))
5) Если же результат сравнения в первом компараторе == 0, то продолжаем в цикле дальше перебирать компараторы до тех пор пока или результат сравнения будет != 0, или не закончатся компараторы и цикл завершится (в этом случае возвращаем 0, это будет означать что объекты T o1 и T o2 по всем трём критериям (колонкам) равны).
как — то так, вроде бы всё понятно объяснил)
IgorChaiun
Спасибо за ответ, задачу уже давно решил, как сформировал вопрос, так и дошло как решать)
По моему я просто циклом в блоке try{} перебирал какой из компараторов сработает, какой первый сработал, такой и результат вернул.
provisota
  • provisota
  • 0
  • Комментарий отредактирован 2014-06-01 14:25:58 пользователем provisota
ну да, вообщем — то алгоритм практически тот же, только try{} тут непонятно зачем) эксепшенов же вроде как не предвидится)
MindIbniM
All hail provisota! =))
levka
СПАСИБА!
vsvld
спасибо!
Sabat
Спасибо!
noroving
Спасибо. Ваш бы ХИНТ в условие задачи). Прошло с первого раза
Bikmop
И от меня спасибо! С первого раза засчитало.
Eva_Sky
Жаль, что нельзя больше 1 раза плюсануть… Ваши комментарии мне уже в стольких задачах помогли! Спасибо-спасибо!
provisota
Всем пожалуйста, рад что получилось так доходчиво объяснить!)
pro100boy
Задача класс. А было б понятнее, если б в условии дописали, что делаем аналог выборки SQL:
SELECT f1, f2, f3,..., fn
FROM table
ORDER BY f1, f2,..., fn
generatorideas
Спасибо, ты реально хороший программист!
V_efire
  • V_efire
  • 0
  • Комментарий отредактирован 2017-01-28 14:30:23 пользователем V_efire
Мне конечно стыдно признаться, но условие я не понял, естественно не совсем вообще ))
Конструктор создал. Что дальше — не ясно.
С компараторомами видимо чего-то недочитал, или недопонял. Задача усложнилась.
Итого, почитав здесь, решил пойти по пути provisota, но на втором пункте тормознул из-за неясности.
Тогда решил писать по примерам еще ниже.
Задача зачлась с первой попытки. И как бы все логично, но есть недопонимание — то ли материала недодали, то ли ушами прохлопал. Последователям дам некоторые подсказки, как мне показалось одного из самых коротких путей решения.
0) класс имплементится от компаратора с дженериком, т.е. Т.
1) идея скажет на счет нужного метода compare с параметрами (T o1, T o2). И никаких других методов не надо.
2) нужна переменная — массив компараторов T.
3) в конструктор приходит массив этих компараторов Т. Делаем как обычно в конструкторе ))
4) в методе компаре (все делается только тут), создаем переменную, которая будет хранить резалт и даем ей нуля (типа все равно), и создаем цикл по нашему массиву, я делал через фор(инт и=0...), чтоб соблюдался порядок полей на все 100%.
5) в этом цикле, берем элемент массива, вызываем его compare с подкинутыми o1 и o2, результат возвращаем в наш резалт.
6) и тут же, смотрим в резалт, если не равен нулю, делаем ретарн этого резалта.

вероятно тоже сильно подсказал, но старался замаскировать все явное русскими буквами…
provisota
Заковыристая задачка, заставляет извилинами пошуршать!) фух! но интересная)
Romanfox
Ахааха!!! Решил с первого раза! Правда два дня голову ломал. provisota , спасибо большое за биг хинт!!!
CoolerB
  • CoolerB
  • 0
  • Комментарий отредактирован 2014-09-01 17:38:04 пользователем CoolerB
что-то я торможу, у меня подсвечивается Т в Comparator как ошибку, предлагает такой класс создать, как компилятору объяснить, что это женерик?
Don
Класс тоже должен быть обобщен, тем-же типом.
rmk
  • rmk
  • 0
  • Комментарий отредактирован 2015-01-03 12:13:08 пользователем rmk
good task)
superz600
Да, задача прикольная, аж даже какую-то гордость ощущаешь :) не зря предыдущие 25 уровней прошли :)
volko
Ох. Пока собственную таблицу и сортировку полей с main'ом не создала так и не поняла условия задачи.
Решить удалось, но остался непонятым вопрос о дженериках. Повсюду где только можно натыкала
<T>
. Из-за чего есть одно предупреждение (warning) IDEA — «Possible heap pollution from parameterized vararg type» в конструкторе класса CustomizedComparator. Из-за чего это и как от этого предупреждения избавиться?
Кто-нибудь решил задачу без предупреждений IDEA?
ksil
main сбросите?
DmitriyL
Запилил свой компаратор. Решение не прошло, хоть и сравнивает все правильно. Пришел сюда, прочитал коммент Провисоты. Сравнил со своим решением, вроде все сходится, но задача не принимается.

public static class CustomizedComparator<T> implements Comparator<T>
    {
        ArrayList<Comparator<T>> comparators;
        public CustomizedComparator(Comparator<T>... comparators)
        {
            this.comparators = new ArrayList<>(comparators.length);
            Collections.addAll(this.comparators, comparators);
        }

        @Override
        public int compare(T o1, T o2)
        {
            int result = 0;

            for (int i = 0; i < this.comparators.size(); i++)
            {
                result += this.comparators.get(i).compare(o1, o2) * Math.pow(10, 6 * this.comparators.size() - 1 - i);
            }
            return result;
        }
    }


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

Может кто объяснить, в чем я не прав.

Сейчас попробую переделать с проверками на ноль. Скорее всего пройдет. Но почему моя логика не верна? Где я ошибку допустил?
DmitriyL
Мда. Действительно прошло.
DmitriyL
Ну собственно, я понял где может быть ошибка. если результат выполнения следующих компараторов окажется соразмерным с результатом выполнения предыдущих компараторов, то итоговый результат будет не верен.

Хотя я помню в каком то из первых уровней что-то подобное решалось именно таким способом. Или нет.
mbllllb
Пытаюсь разобраться в теме и не понимаю:
а почему ваш метод
public int compare(T o1, T o2)
такой сложный? Уже убился, но не могу понять, зачем результат compare(o1, o2) умножать на 10 в такой огромной степени а затем отнимать 1 и i…
Почему нельзя просто
public int compare(T o1, T o2) {
            for (Comparator item : list) {
                int comp = item.compare(o1, o2);
                if (comp != 0) return comp;
            }
            return 0;
        }

То ли я ничего не понял про компаратор и тут ошибка валидатора (что он у меня принял), то ли я решил тоже верно, просто короче…
DmitriyL
Да, ты все верно сделал. Тот код, который я выложил невалидный (его не принимал валидатор, как ни странно)))). А валидный я уже не выкладывал. Ты прав. И все понял верно.
che18
Почему в качестве входного параметра конструктора не подходит List?
boyfromspb
Правильный вопрос. Если посмотреть комментарий DmitriyL , можно увидеть входной параметр переменной длины. Я изначально реализовал передачей листа компараторов и проверкой длины с генерацией исключения в случае если лист пусто. Но его решение лучше, т.к. делает код чистым, более компактным и содержит это требование уже в себе, не явно.

Хотя, мне кажется, что правильным должно быть и одно и другое решение.
che18
Видимо именно в этом причина. Спасибо!
VladTrygub
Да, в этом и была причина, нужно делать массив переменной длины.
PodKrepkimCh
а разве при передаче переменного количества аргументов их количество не может быть равно нулю?
kapodes
Тоже прошло только когда поменял List на массив Comparator. Минус условию задачи(
rublin
+1
По условию «1. в конструкторе принимать список компараторов». На сколько я помню, список принято считать List. По этому и я не сдал с первого раза…
ttt
  • ttt
  • 0
Как то не соображу почему не принимает
public static class CustomizedComparator<T> implements Comparator<T>{
        private ArrayList<Comparator <T>> arrayListOfComparators;

        public CustomizedComparator(Comparator <T> [] comparators)
        {
            for(Comparator<T> comparator: comparators)
                this.arrayListOfComparators.add(comparator);
        }

        @Override
        public int compare(T o1, T o2)
        {
            for(Comparator<T> comparator: arrayListOfComparators)
                if(comparator.compare(o1,o2)!=0)
                    return comparator.compare(o1,o2);
            return 0;
        }
    }
Arcanum
А кто будет инициализировать поля? ;)

Обидно, но задачу у меня не принимало только потому, что конструктор не должен быть с параметром List
Приняло с vararg.
ab_random
Не так давно была задача lvlel25.lesson02.home01 со списком колонок и видимостью — про List в конструкторе даже не подумал, но долго тупил, где взять Enum:)
losemind
Просьба к администрации. Откорректируйте условие задачи. Из-за того что там написано «в конструктор передается список» решил не с первой попытки, а с 3. Ибо массив и список это разные вещи и это реально сбивает с толку.
Joysi
+1. Похоже 90% наступает на одни и те же грабли.
Alexey007gold
Офигеть, я тоже с 3 раза сдал только из-за того что Лист не проходит.
barbudos
  • barbudos
  • 0
  • Комментарий отредактирован 2016-08-12 22:54:34 пользователем barbudos
Насколько я понимаю, под списком параметров понимается следующая реализация:

<code>
        public CustomizedComparator(Comparator... comparators) {
            this.comparators = comparators;
        }
</code>

Что означает, что в коде можно писать как-то так:
<code>
Comparator c1 = new CustomizedComparator(comp1);
//или так
Comparator c2 = new CustomizedComparator(comp1, comp2);
//или так
Comparator c3 = new CustomizedComparator(comp1, comp2, comp3);
</code>
Т.е. возможно любое количество входных параметров. Поэтому с List задача не принимается.

p.s. Поправьте меня, если я не прав.
barbudos
Кстати, объясните фразу «Все переданные компараторы сортируют дженерик тип Т»

Долго думал, как это реализовать и куда впихнуть дженерик. В итоге просто забил на эту строку, реализовал решение так, как мне думалось правильным и задача принялась! Я очень удивился :)
mainbord
  • mainbord
  • 0
  • Комментарий отредактирован 2016-11-11 12:57:46 пользователем mainbord
Так в этом вся и фишка. Компаратор у нас generic, поэтому мы должны указывать его тип. Но вот проблема! Мы не знаем его тип. Поэтому мы говорим, что наш класс параметризирован то есть
CustomizedComparator<T>

то есть пользователь класса сам скажет какой будет тип при написании кода.
И теперь этот параметр аналогично передаём компаратору, то есть теперь мы используем
Comparator<T>
mainbord
Не сдал с первого раза. Полез на форум. Оказалось нужно делать проверку на ноль.

Спрашивается вот что!

«В конструктор передается как минимум один компаратор»
Зачем эта фраза, если нужно проверять передаётся 0 или нет?

А так хороша задачка. Хоть увидел как обобщениями пользоваться.
KarmaHacker
Может кто-нибудь объяснить почему метод сортировки
public int compare(T o1, T o2) {
    for (Comparator<T> com : comparators){
        if(com.compare(o1, o2) != 0)
            return com.compare(o1, o2);
    }
    return 0;
}

не принимается валидатором? Что тут не так в чем подводный камень?
Принялось, когда добавил переменную result и поставил брейк, если резулт != 0.
Ведь по сути то написано то же самое, только меньше кода, или все же не тоже самое?
Iona
  • Iona
  • 0
У меня не принимается конструктор. Перепробовал всё что только мог. ЧЯДНТ?

public CustomizedComparator(Comparator<T>... vararg) {
    comparators = new Comparator[vararg.length];
    for (int i = 0; i < vararg.length; i++) {
        comparators[i] = vararg[i];
    }
}
fatfaggy
а T «объявлено» где-то? на уровне класса например?
Iona
Не понял мысль. Разве это не входной параметр для нашего компаратора?
fatfaggy
если у тебя класс типизирован T — тогда ок.
например:
public class MyClass<T> {
    ...
}

но тогда и конструктор сам будет немного по-другому выглядеть вроде…

если нет, но тебе очень надо чтобы метод работал с дженериками — то у тебя тогда перед названием метода должно быть «объявлено» это T
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.