Как отсортировать 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;
}
}