Софтуерно Инженерство
Loading...
ucko0o avatar ucko0o 1 Точки

Сортиране на лист от обекти по дадено property ?

Здравейте, някой би ли ми казал как се сортира лист от Обекти по дадено пропърти(със stream) , което е число(примерно int години или double оценка) ? Понеже успях да разбера как става само с compareTo, но важи само за стрингове.

Благодаря предварително !

Тагове:
0
Fundamentals Module
KeepCoding avatar KeepCoding 442 Точки

Номерът е да се опиташ да пресъздадеш ефектът на ".compareTo" методът. Документацията на метода гласи че връща "a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object."

Нека има клас, който има поле age (и гетър за това поле) и искаш да сортираш по това поле. Пресъздаването на .compareTo методът ще изглежда така:

studentList = studentList.stream()
                .sorted((s1, s2) -> {
                    int comparisonResult = s1.getAge() - s2.getAge();
                    return comparisonResult;
                }).collect(Collectors.toList());


Може да се направи и с Integer.compare. Но ако сравняваш double стойности, то тогава може да вкараш и малко повече логика в сравнението. Напр. да искаш да се сравняват до втори знак. Т.е. при сравнение на 4.0000001 и 4.0000002 ако искаш резултатът да са равни, то стриймът ще изглежда някак така:

studentList = studentList.stream()
                .sorted((s1, s2) -> {
                    double difference = s1.getGrade() - s2.getGrade();
                    if (difference < 0.01d)
                        return 0;

                    else return Double.compare(s1.getGrade(), s2.getGrade());
                })
                .collect(Collectors.toList());

Последният начин, по който се сещам че могат да се сравняват обекти по дадено поле е да си overload-неш compareTo методът. Това става като напишеш "implements Comparable<SameClass>". Ето пример:

public class Student implements Comparable<Student> {
    private int age;
    private Double grade;

    @Override
    public int compareTo(Student anotherStudent) {
        int comparisonResult = this.age - anotherStudent.age;
        if (comparisonResult == 0) //if they are equal
            comparisonResult = Double.compare(this.grade, anotherStudent.grade);

        return comparisonResult;
    }
}

И после извикваш .compareTo методът на твоят обект.
 

studentList = studentList.stream()
                .sorted((s1, s2) -> s1.compareTo(s2))
                .collect(Collectors.toList());

 

2
ucko0o avatar ucko0o 1 Точки

Благодаря много за изчерпателния отговор !

0
ucko0o avatar ucko0o 1 Точки

Вторият начин, който си ми показал, ми сортира списъка от студенти, по оценка, но във възходящ ред , как мога в случая да го променя да е в низходящ, както е по условие в моя случай ? 

0
KeepCoding avatar KeepCoding 442 Точки

Само разменяш стойностите, които се сравняват

else return Double.compare(s1.getGrade(), s2.getGrade());

ще стане

else return Double.compare(s2.getGrade(), s1.getGrade());

Ако питаш за другият начин то ще стане от .sorted((s1, s2) -> s1.compareTo(s2)) на .sorted((s1, s2) -> s2.compareTo(s1))

1
ucko0o avatar ucko0o 1 Точки

Сега се получи, Благодаря ти за отделеното време !

0