[英]In TreeSet, Sorting & Uniqueness of custom objects based on different properties
以下是我的學生班
class Student implements Comparable {
String name;
int rollNo;
@Override
public int compareTo(Object obj) {
return ((Student)obj).name.compareTo(this.name);
}
}
最新修改:但仍然沒有得到正確的結果
@Override
public int compareTo(Object obj) {
Student s = (Student) obj;
if (name.equals(s.name)) { // achieving uniqueness
return 0;
} else {
if (rollNo < s.rollNo) {
return -1;
} else if (rollNo > s.rollNo) {
return 1;
} else {
// this makes `name` the second ordering option.
// names don't equal here
return name.compareTo(s.name);
}
}
}
如果我創建了TreeSet <Student>的對象,我將根據唯一名稱獲取Student對象的排序列表,並按名稱排序。
但是我需要在我的TreeSet <Student>中使用student-rollNo訂購的唯一學生姓名。
比較器可以嗎? 任何人都可以幫助我,每個建議都表示贊賞。 謝謝。
更新:這是完整的程序:
public class Student implements Comparable {
int rollNo;
String name;
Student(String n,int rno) {
rollNo=rno;
name=n;
}
/**
* @param args
*/
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
ts.add(new Student("bbb",2));
ts.add(new Student("aaa",4));
ts.add(new Student("bbb",2));
ts.add(new Student("ccc",3));
ts.add(new Student("aaa",1));
ts.add(new Student("bbb",2));
ts.add(new Student("bbb",5));
System.out.println(ts);
}
@Override
public int compareTo(Object obj) {
Student s = (Student) obj;
if (name.equals(s.name)) { // achieving uniqueness
return 0;
} else {
if (rollNo < s.rollNo) {
return -1;
} else if (rollNo > s.rollNo) {
return 1;
} else {
// this makes `name` the second ordering option.
// names don't equal here
return name.compareTo(s.name);
}
}
}
@Override
public String toString() {
return name + rollNo;
}
}
更新:2:謝謝大家的建議,我還需要更多:)
/*
* Actual scenario is having different properties,
* So here I am just relating my actual scenario with Student class
*/
class Student implements Comparable {
// sorting required on rollNo
int rollNo;
// Unique name is required
String name;
Student(String n, int rno) {
rollNo = rno;
name = n;
}
/**
*
* @param args
*/
public static void main(String[] args) {
TreeSet<Student> tsName = new TreeSet<Student>();
// here by default, order & uniqueness by name only
tsName.add(new Student("ccc", 2));
tsName.add(new Student("aaa", 4));
tsName.add(new Student("ddd", 1));
tsName.add(new Student("bbb", 3));
tsName.add(new Student("ddd", 5));
// output: aaa:4, bbb:3, ccc:2, ddd:1
System.out.println(tsName);
// creating new comparator for student RollNo
TreeSet<Student> tsRollNo = new TreeSet<Student>(new Comparator<Student>() {
public int compare(Student stud1, Student stud2) {
return new Integer(stud1.rollNo).compareTo(stud2.rollNo);
}
});
tsRollNo.addAll(tsName);
System.out.println(tsRollNo);
// now got the desire output: ddd:1, ccc:2, bbb:3, aaa:4
}
public boolean equals(Object obj) {
// internally not used to check equality while adding objects
// in TreeSet
System.out.println("equals() for " + this + " & " + ((Student) obj));
return false;// return false/true doesn't make any sense here
}
@Override
public int compareTo(Object obj) {
Student s = (Student) obj;
// internally inside TreeSet, compareTo is used to decide
// whether two objects are equal or not,
// i.e. compareTo will return 0 for same object(here student name)
System.out.println("compareTo() for " + this + " & " + ((Student) obj));
// achieving uniqueness
return name.compareTo(s.name);
}
@Override
public String toString() {
return name + ":" + rollNo;
}
}
輸出 :
compareTo() for aaa:4 & ccc:2
compareTo() for ddd:1 & ccc:2
compareTo() for bbb:3 & ccc:2
compareTo() for bbb:3 & aaa:4
compareTo() for ddd:5 & ccc:2
compareTo() for ddd:5 & ddd:1
[aaa:4, bbb:3, ccc:2, ddd:1]
[ddd:1, ccc:2, bbb:3, aaa:4]
朋友,無論我使用兩個比較器得到什么,是否有可能在添加對象時實現相同的目標? 我不能先添加元素然后使用新的比較器來實現所需的順序。
我正在操縱數以千計的價值,因此也需要考慮性能。
在TreeSet
它將使用比較器,同時添加用於排序和唯一檢查的元素,
現在的問題是,如果你使用比較器滾動否,你將按照滾動號和唯一滾動nos進行排序。 你不能把兩者放在一起。
我建議你去。
TreeSet
在這里集中關於重復刪除 ArrayList
並按照您想要的任何順序對其進行排序 @ralph對使用帶有指定比較器的TreeSet
的答案很好,使用它。
您應該將一個“學生數據庫”的概念包含在一個暴露和記錄正確行為的類中,而不僅僅是使用原始集合。 如果獲得特定訂單的學生列表是一項設計要求,則公開方法(可能返回Iterable<Student>
表示這一點。在幕后,您可以根據使用模式做各種事情:
Set
和/或Maps
排序/索引學生。 Arrays.sort()
和指定的Comparator
進行按需就地數組排序。 例....
final class StudentTable {
private static final Comparator<Student> studentRollNoComparator = ...;
private final SortedSet<Student> sortedByRollNo =
new TreeSet<Student>(studentRollNoComparator);
public Iterable<Student> studentsOrderedByRollNo()
{
return sortedByRollNo;
}
//see below
public void addStudent(final Student foo) { ... }
}
您需要在Student
類上覆蓋equals()
和hashCode()
,以僅比較學生姓名。 然后,您將在TreeSet
獲得唯一性(靜默)。 顯然,如果你這樣做,你需要進行防御性newStudent
,以便在插入newStudent
之前檢查是否有studentSet.contains(newStudent)
,這樣你就知道你是否有重復。
final class Student implements Comparable {
...
@Override
public boolean equals(Object o)
{
return o!=null &&
o (instanceof Student) &&
((Student)o).name.equals(this.name);
}
@Override
public int hashCode()
{
return name.hashCode(); // good enough for this purpose
}
}
有了這個,那么插入學生的代碼可能如下所示:
void addNewStudent(final Student toAdd)
{
if (studentSet.contains(toAdd)) {
throw new IllegalStateException("Student with same name as "+toAdd+" already exists.");
}
studentSet.add(toAdd);
}
然后,您的樹集中充滿了名稱唯一的學生,如果沒有,您的添加操作將報告失敗。 (拋出異常僅僅是一條潛在的路線,只有在添加具有重復名稱的學生時才適用,這是一個例外情況,但你沒有說。)
您可以使用不同的比較器初始化新的TreeSet。 - 所以你要做的就是編寫一個新的Comparator(實現java.util.Comparator接口),使用這個比較器初始化一個新的TreeSet,然后將所有學生添加到集合中。
TreeSet<Student> sortedByRollNo new TreeSet<Student>(new RollNoComparator());
sortedByRollNo.addAll(allStudents);
TreeSet<Student> sortedByY new TreeSet<Student>(new YComparator());
sortedByY.addAll(allStudents);
每個樹集可以有自己的比較器進行排序,如果沒有指定比較器,則樹集使用集合元素的自然順序。
添加
如果您只需要名稱uniqe Students,那么您有兩種方式:
有點像這樣:
TreeSet<Student> sortedByRollNo new TreeSet<Student>(new RollNoComparator());
sortedByRollNo.addAll(new TreeSet<Student>(allStudends)); //this uses the native comparator to filter by uniqe name
對不起,到這里來晚了,這是一個優雅的解決方案:
public class OwnSortedList<T> extends TreeSet<T> {
private static final long serialVersionUID = 7109828721678745520L;
public OwnSortedList(Comparator<T> levelScoreComparator) {
super(levelScoreComparator);
}
public boolean add(T e) {
boolean existsElement = false;
Iterator<T> it = iterator();
while(it.hasNext() && !existsElement){
T nextElement = it.next();
if(nextElement.equals(e)){
// Element found
existsElement = true;
Comparator<? super T> comparator = comparator();
int compare = comparator.compare(nextElement, e);
if(compare > 0){
remove(nextElement);
super.add(e);
//element added so return true
return true;
}
}
}
if(!existsElement){
super.add(e);
}
return false;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.