排序集合wrt原始值

时间:2012-10-30 11:00:12

标签: java collections

假设我有一个带有卷号和名字的学生班。我想用卷号来解决它。我尝试了以下内容。这是我的代码:

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秒)

5 个答案:

答案 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;
}

注意: - 只有signCollections.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

因此,您可以使用一些计算哈希码的公式来考虑您的1rollNo,而不是简单地返回值large prime number

您可以浏览Effective Java - Item#9以获取有关此主题的更多说明。


现在,您的代码工作正常,让我们转向您的第二个疑问。

如果要比较equals时将使用的两个对象,则不使用

hashCodesorting方法。我们重写equalshashCode方法,以便稍后检查实例是否等于另一个实例。 因此,compareTo方法不关心您是否使用了equals ad hashCode方法。您还可以从名称推断这两种方法的作用,以及它们是否相关。

此外,equals类中定义了Object方法,而compareTo接口中定义了Comparable方法。所以,它们并不相互关联。

查看这些方法的文档: - Object#equalsObject#hashCodeComparable#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比较示例。

Check this link