Как предотвратить дублирование элементов по одному параметру при сортировке по другому параметру, Структуры данных, Kotlin - PullRequest
0 голосов
/ 23 февраля 2020

Предположим, что class Student с параметрами name, grade и ID:

class Student (name: String, grade: String, ID: String) {  
    var _studentID = ID
    var _studentName = name
    var _studentGrade = grade

    //override hashCode(), equals(), compareTo() etc
}

Как предотвратить повторяющиеся записи в соответствии с ID, сортируя их - автоматически, если это возможно - в соответствии с name?

Нельзя использовать ArrayList внутри for l oop для проверки дубликатов, затем использовать функцию sortBy. Такой подход позволяет мне также дать отзыв пользователю. Тем не менее, может быть лучший алгоритм или структура данных (например, HashSet, TreeMap et c.) Для работы. Что порекомендуете?

PS Я тоже попробовал TreeSet. Но каким-то образом TreeSet иногда допускал в набор экземпляры с похожими идентификаторами (скажем, 1 из 5 последовательных попыток). У вас есть идея, как это произошло? Может ли это быть из-за того, что разные потоки работают с одними и теми же данными или из-за несовместимых методов equals() и compareTo() (equals() был переопределен для ID, а compareTo() был переопределен согласно name)?

1 Ответ

0 голосов
/ 24 февраля 2020

TreeSet будет лучшим выбором, если вы хотите сохранить sorted data set. потому что он обеспечивает гарантированную log(n) стоимость времени для базовых c операций (добавить, удалить и содержать).

Чтобы использовать его, вам нужно будет определить natural ordering для вашего класса, реализовав Comparable , или вам придется предоставить comparator.

При реализации Comparable для TreeSet вы должны отметить одну вещь, из TreeSet и Comparable docs

Обратите внимание, что порядок поддерживается набором (независимо от того, является ли он явным или нет). компаратор) должен соответствовать с равными, если он должен правильно реализовать интерфейс Set

Естественный порядок для класса C называется равным тогда и только тогда, когда e1.compareTo (e2) == 0 имеет то же логическое значение, что и e1.equals (e2)

Теперь нужно реализовать Comparable способом, который согласуется с приведенным выше Скажите, вы бы сделали следующее.

class Student (name: String, grade: String, ID: String): Comparable<Student>{
    var studentID = ID
    var studentName = name
    var studentGrade = grade

    // Use the default equals generated by your IDE, but only take into accout ID field
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as Student
        if (studentID != other.studentID) return false
        return true
    }

    // Whenever you override equals, you also need to override hashCode
    override fun hashCode() = studentID.hashCode()

    // Define natural ordering
    override fun compareTo(other: Student): Int {
        if(equals(other)) return 0
        var nameComparison = studentName.compareTo(other.studentName)
        return when(nameComparison){
            // If two objects are equal when compared by name then we sort them by id
            0 -> studentID.compareTo(other.studentID)
            else -> nameComparison
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...