在TreeSet中,排序&基于不同属性的自定义对象的唯一性
以下是我的 Student 类
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
但我需要在我的 TreeSet
用比较器可以吗?任何人都可以帮助我,每个建议都会受到赞赏。 谢谢。
更新:这是完整的程序:
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]
< b>朋友们,无论我使用两个比较器得到什么,是否有可能 添加对象时达到相同的效果? 我不能先添加元素 &然后使用新的比较器来实现所需的顺序。
我正在操纵数千个值,因此还需要考虑性能。
Below is my Student class
class Student implements Comparable {
String name;
int rollNo;
@Override
public int compareTo(Object obj) {
return ((Student)obj).name.compareTo(this.name);
}
}
latest modification: but still no getting the right result
@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);
}
}
}
If I create object of TreeSet<Student>, I am getting sorted list of Student objects based on unique name & ordered by name also.
But I need unique student-name in my TreeSet<Student> with order by student-rollNo.
Is it possible with Comparator? Can anybody help me, Every suggestion is appreciated.
Thanks.
UPDATE: here is the complete program:
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;
}
}
Update:2: Thank you all for your suggestions, I still need some more :)
/*
* 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;
}
}
OUTPUT:
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]
Friends, whatever I got by using two Comparators, Is it possible to
achieve the same while adding the objects ??
I cannot first Add elements & then use new comparator to achieve the desired order.
I am manipulating thousands of values so need to consider performance also.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在
TreeSet
中,它将在添加元素进行排序和唯一检查时使用比较器,现在的问题是,如果您对卷号使用比较器,您也会按卷号和唯一卷号对其进行排序。你不能在树集中同时拥有两者。
我建议你去。
TreeSet
在这里,您专注于重复删除,ArrayList
并按照您想要的任何顺序对其进行排序in
TreeSet
It will use comparator while adding elements for sorting and unique check,now the problem is if you use comparator for roll no you will have it sorted by roll no and unique roll nos too. you can't have both together in treeset.
I would suggest you to go for.
TreeSet
here you concentrate about duplicate removalArrayList
and sort it in any order you want订购
@ralph 的答案 使用具有指定比较器的
TreeSet
是一个很好的选择,请使用它。设计
您应该将“学生数据库”的概念包装在一个类中,该类公开并记录正确的行为,而不是仅仅使用原始集合。如果按特定顺序获取学生列表是设计要求,请公开方法(可能返回表示这一点的
Iterable
)。在幕后,您可以根据使用模式执行各种操作:集合
和/或地图
,按感兴趣的领域对学生进行排序/索引。Comparator
。...唯一
性
您需要重写
equals()
和hashCode()
。 >Student 类,仅比较学生姓名,然后您将在TreeSet
中获得唯一性,显然,如果您这样做,则需要进行防御性编码以进行检查。在插入newStudent
之前查看是否studentSet.contains(newStudent)
,这样您就知道是否有重复项,然后您的代码就可以了 。插入学生可能看起来像:
然后,您的树集中充满了姓名唯一的学生,如果不是,您的添加操作将报告失败。 (抛出异常只是一种潜在的途径,并且仅当添加具有重复姓名的学生实际上是一种异常情况时才适用,但您没有说。)
Ordering
The answer by @ralph on using a
TreeSet
with a specified comparator is a good one, use that.Design
You should wrap your concept of a "student database" inside a class that exposes and documents the correct behaviors, rather than just using a raw collection. If obtaining lists of students in particular orders is a design requirement, expose methods (perhaps returning
Iterable<Student>
that say that. Behind the scenes, you can do a variety of things depending on the usage pattern:Set
s and orMaps
sorting/indexing students by fields of interest.Arrays.sort()
and a specifiedComparator
.Example....
Uniqueness
You need to override
equals()
andhashCode()
on yourStudent
class, to compare only the student name. Then you'll get uniqueness (silently) in yourTreeSet
. Obviously, if you do this, you need to code defensively to check to see ifstudentSet.contains(newStudent)
before insertingnewStudent
, so you'll KNOW whether you've got a duplicate or not.With this in place, then your code to insert student can look like:
Your treeset is then full of students whose names are unique, and your add operation reports a failure if not. (Throwing an exception is just one potential route, and only appropriate if adding a student with a duplicate name is ACTUALLY an exceptional condition, but you didn't say.)
您可以使用不同的比较器初始化新的 TreeSet。 - 所以你所要做的就是编写一个新的Comparator(实现java.util.Comparator接口),使用这个比较器初始化一个新的TreeSet,然后将所有学生添加到该集合中。
每个树集可以有自己的比较器进行排序,如果没有指定比较器,则树集使用集合元素的自然排序。
添加
如果你只需要名字uniqe Students,那么你有两种方法:
有点像这样:
You can initialize a new TreeSet with an different comparator. - So all you have to do, is to write an new Comparator (implements java.util.Comparator interface), use this comparator to initialize the a new TreeSet and then add all students to the set.
Each Tree Set can have its own comparator for sorting, if no comparator is specifed, then the Tree Set uses the natural ordering of the set elements.
added
If you need only the name uniqe Students, then you have two ways:
A bit like this:
抱歉来晚了,这是一个优雅的解决方案:
Sorry for being to late here, here is an elegant solution: