Как отсортировать TreeSet по возрастанию и убыванию в Java

Не получается отсортировать TreeSet по одному из элементов класса Вот как выглядит задание:

В файле “a.csv” записан список студентов, сдававших экзамены, с указанием фамилии, группы и отметок. Информация о каждом студенте хранится в отдельной строке. Прочитать информацию в связный список (LinkedList). Создать две коллекции типа TreeSet. Элементами TreeSet являются объекты, содержащие фамилию и средний балл студента. В первой коллекции списки отсортировать по возрастанию среднего балла во второй – по убыванию. Новые коллекции распечатать на экран.

Что у меня получилось написать на данный момент(пробовал с помощью Comparable):

import java.io.*;
import java.util.*;

class Capital {
    String name;
    String group;
    ArrayList<Integer> grade = new ArrayList<>();
    double sr;
}

class Asd implements Comparable<Asd>{
    String fname;
    double midd;
    public Asd (String ffname,double mid){
        fname = ffname;
        midd = mid;
    }
    public int compareTo(Asd o) {
        return Double.compare(midd,o.midd);
    }
}


public class Main {

    public static void main(String[] args) {
        String path = "a.csv";
        String line = "";
        LinkedList<Capital> list = new LinkedList<>();
        TreeSet<Asd> tree1 = new TreeSet<>();
        TreeSet<Asd> tree2 = new TreeSet<>();
        try {
            BufferedReader br = new BufferedReader(new FileReader(path));

            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                Capital ex = new Capital();
                ex.name = values[0];
                ex.group = values[1];
                for (int i = 2; i < (values.length - 1); i++) {
                    int num = Integer.parseInt(values[i]);
                    ex.grade.add(num);
                }
                list.add(ex);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
     
        for (Capital s : list) {
            double sum = 0;
            for (int j = 0; j < s.grade.size() - 1; j++) {
                sum += s.grade.get(j);
            }
            double sred = sum / s.grade.size();
            s.sr = sred;
            tree1.add(new Asd(s.name,s.sr));
            tree2.add(new Asd(s.name,s.sr));
        }
        for (Asd s : tree1) {
            System.out.println(s.fname);
            System.out.println(s.midd);
        }
    }
}

Пример данных в файле:
Павлов,нп02,3,5,2,4,3,5
Иванов,нп3,5,4,5,3,5,2,4,5
Аксенов,нп02,4,5,3,4,2,4,5,5


Ответы (1 шт):

Автор решения: Дмитрий

Чтобы отсортировать TreeSet достаточно указать порядок сортировки, который определен либо самим объектом путем имплеиментации интерфейса Comparable, либо с помощью интерфейса Comparator, который можно передать в конструктор. Второй способ в данном случае подходит лучше. Но это не основная проблема вашего кода. Вы нарушаете самые фундаментальные принципы, включая принципы ООП. Код излишне сложный. Кроме того, вы допустили ошибку в цикле for (int i = 2; i < (values.length - 1); i++), где следовало использовать for (int i = 2; i < values.length; i++), иначе вы всегда будете пропускать последнюю оценку студента. Посему разберите данное решение и, если возникнут какие-либо вопросы, задавайте их в комментариях:

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;

public class Main {

    public static void main(String[] args) throws IOException {

        String path = "a.csv";
        List<Capital> list = readFromFile(path);

        Set<Capital> orderTreeSet = new TreeSet<>(Comparator.comparingDouble(Capital::getAvg));
        orderTreeSet.addAll(list);

        Set<Capital> reverseTreeSet = new TreeSet<>(Comparator.comparingDouble(Capital::getAvg).reversed());
        reverseTreeSet.addAll(list);

        print(orderTreeSet);
        System.out.println("*********************************");
        print(reverseTreeSet);

    }

    private static List<Capital> readFromFile(String path) throws IOException {
        List<Capital> capitals = new LinkedList<>();
        Scanner sc = new Scanner(Paths.get(path), "UTF-8");        
        while (sc.hasNext()) {
            String[] values = sc.nextLine().split(",");
            Double average = IntStream.range(2, values.length)
                    .map(i -> Integer.valueOf(values[i]))
                    .average().getAsDouble();
            capitals.add(new Capital(values[0], values[1], average));
        }
        return capitals;
    }

    private static void print(Iterable args) {
        StreamSupport.stream(args.spliterator(), false).forEach(System.out::println);
    }

}

class Capital {

    private final String name;
    private final String group;
    private final Double avg;

    public Capital(String name, String group, Double avg) {
        this.name = name;
        this.group = group;
        this.avg = avg;
    }

    public String getName() {
        return name;
    }

    public String getGroup() {
        return group;
    }

    public Double getAvg() {
        return avg;
    }

    @Override
    public String toString() {
        return name + " : " + avg;
    }

}
→ Ссылка