Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Двойное условие сортировки листа ( Comparator )

#java #android


Имеется класс:

public class Man (){

    private int rating1;
    private int rating2;

    Man (int rating1, int rating2){
        this.rating1 = rating1;
        this.rating2 = rating2;
    }

    public int getRating1(){
        return rating1;
    }

    public int getRating2(){
        return rating2;
    }
}


Формируется List по rating2 (по убыванию):

public class MyComporatorByRating implements Comparator {

    @Override
    public int compare(man o1, man o2) {
        return Integer.compare(o2.getRating1(), o1.getRating1());
    }

}


Что необходимо добавить в MyComporatorByRating, чтобы вначале списка были только
те Man, у которых rating2 от 1 до 5 в порядке возрастания.

Т.е. первыми в списке List были отсортированы Man по значению rating2 от 1 до 5 (значения
rating1 у них игнорируются), а потом все остальные Man по rating1 от 100 до 0 (значение
rating2 у них 0)?
    


Ответы

Ответ 1



public class Man { private int rating1; private int rating2; Man(int rating1, int rating2) { this.rating1 = rating1; this.rating2 = rating2; } public int getRating1() { return rating1; } public int getRating2() { return rating2; } public CompareWith getCompareWith() { if(rating2 >= 1 && rating2 <= 5) { return CompareWith.RATING2; } return CompareWith.RATING1; } public enum CompareWith { RATING1, RATING2 } } И компаратор: public class MyComporatorByRating implements Comparator { @Override public int compare(Man o1, Man o2) { if(CompareWith.RATING2.equals(o1.getCompareWith()) && CompareWith.RATING2.equals(o2.getCompareWith())) { return o1.getRating2() - o2.getRating2(); } else if(CompareWith.RATING2.equals(o1.getCompareWith())) { return 1; } else if(CompareWith.RATING2.equals(o2.getCompareWith())) { return -1; } else { return o2.getRating1() - o1.getRating1(); } } }

Ответ 2



@Override public int compare(Coordinates o1, Coordinates o2) { int result = Integer.compare(o1.getX(), o2.getX()); if (result != 0) { return result; } return Integer.compare(o1.getY(), o2.getY()); } примерно так. Этот компаратор сравнивает координаты в моём проекте. Сначала сравнивает ось Х, если Х одинаковы, то сравнивает по оси Y. Действуй по аналогии

Ответ 3



Если вы используете Java 8+, то можете воспользоваться новыми возможностями: потоками и лямбдами. Ваш код будет гораздо проще: Comparator comparator = Comparator.comparing(man -> man.rating2); comparator = comparator.thenComparing(Comparator.comparing(man -> -man.rating1)); Stream manStream = men.stream().sorted(comparator); List sortedMen = manStream.collect(Collectors.toList()); Не нужно никаких отдельных классов и ручного сравнения.

Ответ 4



Из Вашего описания следует, что: rating2 є [0, 5], rating1 є [0, 100]. В этом случае, компаратор можно переписать без всякого добавления enum'ов в класс Man. Он будет таким: public class MyComporatorByRating implements Comparator{ @Override public int compare(Man o1, Man o2) { if(o1.getRating2() == 0 && o2.getRating2() == 0){ return -Integer.compare(o1.getRating1(), o2.getRating1()); } else if(o1.getRating2() == 0){ return 1; } else if(o2.getRating2() == 0){ return -1; } else{ return Integer.compare(o1.getRating2(), o2.getRating2()); } } } Также замечу, что оба поля класса Man можно объявить как final (поскольку у Вас нет методов set(), то эти поля неизменяемы).

Комментариев нет:

Отправить комментарий