Непонятно с TreeSet

Добрый день. Хочу реализовать систему подбора кандидатов с TreeSet . Но почему-то сохраняет только первое введенное значение, а дальнейшие значения не сохраняет. Как это исправить?
2. После того как я сделаю ввод нескольких значений, хочу реализовать сортировку по последним двум значениям int. Подскажите, это нормально, если я значения из TreeSet добавлю в ArrayList и затем отсортирую по последним двум значениям через Collections.sort(candidates, compareByRelandRate); , а потом выведу все значения через foreach?

Мой код ниже:

import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class Main  {
    public static void main(String[] args) {
        TreeSetClass treeSetClass = new TreeSetClass();
        Scanner scanner = new Scanner(System.in);
        String input = "";
        printAction();
        while (true) {
            typeInfo();
            input = scanner.nextLine();
            if("".equals(input)){
                break;
            }
            String[] candidateInfo = input.split(", ");
            Candidate candidate;
            if (candidateInfo.length == 5) {
                candidate = new Candidate(candidateInfo[0],
                        candidateInfo[1],candidateInfo[2],
                        Integer.parseInt(candidateInfo[3]),
                        Integer.parseInt(candidateInfo[4]));
                treeSetClass.addCandidate(candidate);
                treeSetClass.displayCandidates();
            }
        }
    }

    public static void printAction() {
        System.out.println("Enter the information about the candidate" +
                " (enter an empty string to complete):");
    }

    public static void typeInfo() {
        System.out.println("Surname First name Patronymic, gender, age, resume relevance, interview grade:");
    }
}



import java.util.Objects;

public class Candidate implements Comparable<Candidate>{
    private String name;
    private String sex;
    private String age;
    private int relevance;
    private int rating;

    public Candidate(String name, String sex, String age, int relevance, int rating) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.relevance = relevance;
        this.rating = rating;
    }

    public int getRelevance() {
        return relevance;
    }



    public int getRating() {
        return rating;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Candidate candidate = (Candidate) o;
        return relevance == candidate.relevance && rating == candidate.rating && name.equals(candidate.name) && sex.equals(candidate.sex) && age.equals(candidate.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, sex, age, relevance, rating);
    }

    @Override
    public String toString() {
        return "Candidate{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                ", relevance=" + relevance +
                ", rating=" + rating +
                '}';
    }

    @Override
    public int compareTo(Candidate o) {
//        Comparator<Candidate> compareByRelandRate = Comparator
//                .comparing(Candidate::getRelevance)
//                .thenComparing(Candidate::getRating);
//        Collections.sort(candidates, compareByRelandRate);
        return 0;
    }
}

import java.util.*;
import java.util.Collections;
 
public class TreeSetClass implements Comparable<Candidate> {
    Set<Candidate> candidates = new TreeSet<>();
    List<Candidate> list = new ArrayList<>();
//    candidates.addAll(list);
 
    public void addCandidate(Candidate candidate) {
        candidates.add(candidate);
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TreeSetClass that = (TreeSetClass) o;
        return Objects.equals(candidates, that.candidates);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(candidates);
    }
 
 
    public void displayCandidates() {
//        Comparator<Candidate> compareByRelandRate = Comparator
//                .comparing(Candidate::getRelevance)
//                .thenComparing(Candidate::getRating);
////        Collections.sort(candidates, compareByRelandRate);
////
//        Set<Candidate> sb =new TreeSet<Candidate>(compareByRelandRate);
 
//        candidates.sort(Comparator.comparing(Candidate::getRelevance));
 
        System.out.println("Candidates list: ");
        for (Candidate info : candidates) {
 
            System.out.println(info);
        }
 
    }
 
    @Override
    public int compareTo(Candidate o) {
        return 0;
    }
}

Останавливает цикл ввода, или продолжает ввод, но не добавляет?
Если второе, то видимо надо смотреть что в

Ну и в любом случае разбирайтесь что именно происходит с помощью отладчика или отладочного вывода.

Второе. Дело в том, что если сменить на HashSet, то всё работает. Но если я поставлю вместо HashSet → TreeSet, а мне нужен TreeSet, то не сохраняет следующие значения

наверно потому что либо

всегда возвращает 0
либо в

что-то не то.

TreeSet же использует что-то из этого для определения порядка, и он не добавляет если уже есть такое значение.

так я абсолютно разные значения добавляю, а TreeSet не хочет их записывать. Только самое первое значение сохраняет и всё…
Вроде бы в equals нет проблемы, а в CompareTo обязательно какую-то логику задать? Просто мне сравнивать попозже надо будет, я бы сначала хотел, чтобы значения TreeSet сохранял…

Дык он не по значениям свойств определяет разные ли они.

TreeSet (Java Platform SE 8 )

a TreeSet instance performs all element comparisons using its compareTo (or compare ) method

Всё получилось. Надо было разобраться с CompareTo и потом сделать самому сравнение по атрибутам

import java.util.Scanner;


public class Main  {
    public static void main(String[] args) {
        TreeSetClass treeSetClass = new TreeSetClass();
        Scanner scanner = new Scanner(System.in);
        String input = "";
        printAction();
        while (true) {
            typeInfo();
            input = scanner.nextLine();
            if("".equals(input)){
                break;
            }
            String[] candidateInfo = input.split(", ");
            Candidate candidate;
            if (candidateInfo.length == 5) {
                candidate = new Candidate(candidateInfo[0],
                        candidateInfo[1],candidateInfo[2],
                        Integer.parseInt(candidateInfo[3]),
                        Integer.parseInt(candidateInfo[4]));
                treeSetClass.addCandidate(candidate);
                treeSetClass.displayCandidates();
            }
        }
    }

    public static void printAction() {
        System.out.println("Enter the information about the candidate" +
                " (enter an empty string to complete):");
    }

    public static void typeInfo() {
        System.out.println("Surname First name Patronymic, gender, age, resume relevance, interview grade:");
    }
}
import java.util.Objects;

public class Candidate implements Comparable<Candidate>{
    private String name;
    private String sex;
    private String age;
    private int relevance;
    private int rating;

    public Candidate(String name, String sex, String age, int relevance, int rating) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.relevance = relevance;
        this.rating = rating;
    }

    public int getRelevance() {
        return relevance;
    }

    public int getRating() {
        return rating;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Candidate candidate = (Candidate) o;
        return relevance == candidate.relevance && rating == candidate.rating && name.equals(candidate.name) && sex.equals(candidate.sex) && age.equals(candidate.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, sex, age, relevance, rating);
    }

    @Override
    public String toString() {
        return "Candidate{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age='" + age + '\'' +
                ", relevance=" + relevance +
                ", rating=" + rating +
                '}';
    }

    @Override
    public int compareTo(Candidate o) {
        int comp = this.name.compareTo(o.name);
        if(comp==0) return this.name.compareTo(o.name);
        return comp;
    }
}
import java.util.*;
import java.util.Collections;

public class TreeSetClass {
    Set<Candidate> candidates = new TreeSet<>(new compareByRate());
    List<Candidate> list = new ArrayList<>();


    public void addCandidate(Candidate candidate) {
        candidates.add(candidate);
    }



    class compareByRate implements Comparator<Candidate> {
        public int compare(Candidate s1, Candidate s2) {
            if (s1.getRelevance() > s2.getRelevance()) {
                return 1;
            }
            if (s1.getRelevance() == s2.getRelevance() && s1.getRating() > s2.getRating()) {
                return 1;
            } else {
                return -1;
            }
        }
    }



    public void displayCandidates() {
        Comparator<Candidate> compareByRelandRate = Comparator
                .comparing(Candidate::getRelevance)
                .thenComparing(Candidate::getRating);
        candidates.addAll(list);
        Collections.sort(list, compareByRelandRate);

        Set<Candidate> sb = new TreeSet<Candidate>(compareByRelandRate);

//        candidates.sort(Comparator.comparing(Candidate::getRelevance));
        System.out.println("Candidates list: ");
        for (Candidate info : candidates) {
            System.out.println(info);
        }

    }


}

Спасибо за помощь Alex!

:thinking: тут написано

a = b;
if (a == 0) return b;
return a;

это ж то же самое, что просто return this.name.compareTo(o.name).

Тут как минимум пропущен случай, когда они равны.

  1. Тут как минимум пропущен случай, когда они равны.

Так я вроде как и зада логику согласно своего задания:

Необходимо хранить данные в TreeSet таким образом, чтобы они сортировались в порядке убывания, по двум атрибутам одновременно “relevance” и “rating”. Поэтому вы можете воспользоваться либо Comparator , с переопределенным методом compare , в котором будут проводиться сравнения по двум полям relevance и rating .

  1. это ж то же самое, что просто return this.name.compareTo(o.name) .

Ну, не совсем то же самое, т.к. я сделал return this.name.compareTo(o.name), чтобы я смог наконец-то сохранять объекты в TreeSet, а

 if (s1.getRelevance() > s2.getRelevance()) {
                return 1;
            }
            if (s1.getRelevance() == s2.getRelevance() && s1.getRating() > s2.getRating()) {
                return 1;
            } else {
                return -1;
            }

реализовано сравнение согласно задания (в п.1 написал как).
Если что-то я не понял или можно как-то лучше, то поправьте меня, пожалуйста.

Когда объекты считаются равными, надо возвращать 0.

Дык причем тут это.
Смотрите

вы зачем-то проверяете, что значение == 0, но независимо от этого возвращаете одно и то же.

Я решил в Candidate сделать так:

@Override
    public int compareTo(Candidate o) {
        int comp = this.name.compareTo(o.name);
        if(comp==0) {
            return 0;
        }
        else {
            return comp;
        }
    }

Правда, это всё равно не удаляет дубли, но так, наверно, архитектурно правильно, как вы говорите…

Для чего этот if?

Наверно, это лишнее
Сделал так:

 @Override
    public int compareTo(Candidate o) {
        return this.name.compareTo(o.name);
    }