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

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

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

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

Тагове:
0
Fundamentals Module
damesova avatar damesova 199 Точки

 

Ако говорим само за Лист - стриймни го, достъпваш пропъртито и го манипулираш с израз. Не става ли?

Ако е някакъв Map с Лист, нещо такова:  Ако пропъртито ти е value, го достъпваш като value. Ако ти е key - като key. Веднъж достъпено, можеш да оперираш с него съвсем нормално. Не знам конкретния ти случай, но някой ламбда израз няма ли да свъши работа?

0
ucko0o avatar ucko0o 1 Точки

Да, точно с поток се прави, но още не сме ги вземали, а имахме задача от упражненията, която не беше решена от преподавателят, и там трябва да сортираме лист от обекти по дадено пропърти на класа, което е оценка и просто ни беше показано как става сортирането по пропърти Стринг, но не и по число :)

0
Hristo13 avatar Hristo13 236 Точки

Примерно за map<String, Integer>

map.entrySet().stream().sorted((e1, e2) -> {

int sort = Integer.compare(e1.getValue(), e2.getValue())

return sort;

})

 

 

Да речем пък имаш map<Integer, List<Double>> и искаш да ги подредиш по дължина на листа

същата работа но малка промяна в реда Integer.compare. Ако искаш да са в ascending order на първи ред пишеш в скобите e1, e2 а ако е в descending ги обръщаш e2, e1

 

1.   map.entrySet().stream().sorted((e1, e2) -> {

2.   int sort = Integer.compare(e1.getValue().size, e2.getValue().size)

3.   return sort;

4. })

 

Или пък лист от double/Integer

List<Integer> qwer

qwer.stream().sorted() - това ги сортира в ascending order тоест 1 4 5 7 40 60 ...

 

 

Дай някакъв конкретен пример ако горните не ти помогнаха.

1
17/03/2019 10:11:12
ucko0o avatar ucko0o 1 Точки

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

0
ucko0o avatar ucko0o 1 Точки

Write a program that receives an n count of students and orders them by grade (in descending). Each student
should have First name (string), Last name (string) and grade (floating-point number).

 

Това е условието на задачата, но така и не успях да ги сортирам и да я реша.

0
Hristo13 avatar Hristo13 236 Точки

Дай pastebin до където си стигнал да я погледна.

0
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