假设我有一个带有卷号和名字的学生班。我想用卷号来解决它。我尝试了以下内容。这是我的代码:
package CollectionDemo;
import java.util.*;
class student1 implements Comparable<student1>{
int rollNo;
String name;
student1(int rollNo,String name){
this.rollNo=rollNo;
this.name=name;
}
@Override
public boolean equals(Object o){
if((o instanceof student1) && (((student1)o).rollNo == rollNo)){
return true;
}
else
{
return false;
}
}
@Override
public int hashCode(){
return 1;
}
public int compareTo(student1 s) {
return s.rollNo;
}
public String toString(){
return "["+rollNo+","+name+"]";
}
}
public class treeSetDemo {
public static void main(String... a){
Set<student1> set=new TreeSet<student1>();
set.add(new student1(102,"Anu"));
set.add(new student1(101,"Tanu"));
set.add(new student1(103,"Minu"));
System.out.println("elements:"+set);
}
}
o/p: elements:[[102,Anu], [101,Tanu], [103,Minu]]
所以,它没有排序:(如何使其正确。
感谢您的帮助。
=============================================== =
感谢您的帮助。下面的代码运行正常,但现在我想知道它是如何工作的,如果我注释掉equals和hashcode方法。
package CollectionDemo;
import java.util.*;
class student1 implements Comparable<student1>{
int rollNo;
String name;
student1(int rollNo,String name){
this.rollNo=rollNo;
this.name=name;
}
/* @Override
public boolean equals(Object o){
if((o instanceof student1) && (((student1)o).rollNo == rollNo)){
return true;
}
else
{
return false;
}
}
@Override
public int hashCode(){
return 1;
}
*/
public int compareTo(student1 s) {
System.out.println("hello:"+(this.rollNo-s.rollNo));
return this.rollNo-s.rollNo;
}
public String toString(){
return "["+rollNo+","+name+"]";
}
}
public class treeSetDemo {
public static void main(String... a){
Set<student1> set=new TreeSet<student1>();
set.add(new student1(102,"Anu"));
set.add(new student1(101,"Tanu"));
set.add(new student1(103,"Minu"));
System.out.println("elements:"+set);
}
}
OP: 跑: 你好:-1 你好:1 要素:[[101,Tanu],[102,Anu],[103,Minu]] 建立成功(总时间:0秒)
答案 0 :(得分:1)
你必须以下面的方式改变compareTo方法
public int compareTo(student1 s) {
if(s.rollNo == this.rollNo){
return 0;
}else if(s.rollNo > this.rollNo){
return -1;
}else{
return 1;
}
}
答案 1 :(得分:0)
在compareTo
方法中,您只是返回要比较的对象的值。您需要返回调用实例的属性和传递的实例的差异。
因此,请将您的compareTo
方法更改为以下方法: -
@Override
public int compareTo(student1 s) {
return this.rollNo - s.rollNo;
}
注意: - 只有sign
对Collections.sort
非常重要,因此您不需要if-else
块来返回-1, 0, or 1
。只要归还差异。就是这样。
P.S:
您的哈希码实现非常糟糕。它会将每个实例放在同一个桶中。
@Override
public int hashCode(){
return 1; // All the instances will have the same hashcode.
}
理想情况下,您应该只使用这些属性来计算用于比较两个实例的hashCode
,此处为rollNo
。
因此,您可以使用一些计算哈希码的公式来考虑您的1
和rollNo
,而不是简单地返回值large prime number
。
您可以浏览Effective Java - Item#9
以获取有关此主题的更多说明。
现在,您的代码工作正常,让我们转向您的第二个疑问。
如果要比较equals
时将使用的两个对象,则不使用 hashCode
和sorting
方法。我们重写equals
和hashCode
方法,以便稍后检查实例是否等于另一个实例。
因此,compareTo
方法不关心您是否使用了equals
ad hashCode
方法。您还可以从名称推断这两种方法的作用,以及它们是否相关。
此外,equals
类中定义了Object
方法,而compareTo
接口中定义了Comparable
方法。所以,它们并不相互关联。
查看这些方法的文档: - Object#equals
,Object#hashCode
和Comparable#compareTo
答案 2 :(得分:0)
- 如果您只想根据一个属性进行排序,请使用java.lang.Comparable<T>
Intereface以及Collections.sort(List l)
。
- 但如果你的目标是根据多个属性对其进行排序,那么请转到java.util.Comparator<T>
和Collections.sort(List l, Comparator c)
。
<强>例如强>
import java.util.Comparator;
public class Fruit implements Comparable<Fruit>{
private String fruitName;
private String fruitDesc;
private int quantity;
public Fruit(String fruitName, String fruitDesc, int quantity) {
super();
this.fruitName = fruitName;
this.fruitDesc = fruitDesc;
this.quantity = quantity;
}
public String getFruitName() {
return fruitName;
}
public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
public String getFruitDesc() {
return fruitDesc;
}
public void setFruitDesc(String fruitDesc) {
this.fruitDesc = fruitDesc;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int compareTo(Fruit compareFruit) {
int compareQuantity = ((Fruit) compareFruit).getQuantity();
//ascending order
return this.quantity - compareQuantity;
//descending order
//return compareQuantity - this.quantity;
}
public static Comparator<Fruit> FruitNameComparator
= new Comparator<Fruit>() {
public int compare(Fruit fruit1, Fruit fruit2) {
String fruitName1 = fruit1.getFruitName().toUpperCase();
String fruitName2 = fruit2.getFruitName().toUpperCase();
//ascending order
return fruitName1.compareTo(fruitName2);
//descending order
//return fruitName2.compareTo(fruitName1);
}
};
}
答案 3 :(得分:0)
我认为这个实现接近推荐:
@Override
public int compareTo(Object other) {
if(other == null || !(other instanceOf student)){
throw new IllegalArgumentException();
}
student s = (student) other;
if(this.rollNo > s.rollNo){
return 1;
} else if (this.rollNo < s.rollNo){
return -1;
} else {
return 0;
}
}
答案 4 :(得分:0)
如果您使用的是Comparable接口,那么您的compareTo()方法应该返回比较不等于方法,Google比较示例。