用于在java中对对象数组进行排序的比较函数?

时间:2013-05-17 06:32:52

标签: java sorting

我有一系列电话簿元素,我正在尝试根据字典顺序对它们进行排序。但这一切都搞砸了。请帮忙。提前致谢

它还有助于描述一下java中的排序函数! 这是代码:

package myphonebook;

import javax.swing.*;
import java.util.Arrays;
import java.util.Comparator;
public class MyPhoneBook implements Comparator<MyPhoneBook>{

    private String name,email,number;
    MyPhoneBook()
    {
    }

    public void input()
    {
        name = (JOptionPane.showInputDialog("Enter Name:\n")).toString();
        number = JOptionPane.showInputDialog("Enter Number:\n").toString();
        email = JOptionPane.showInputDialog("Enter email:\n").toString();
    }
    public void print()
    {
        JOptionPane.showMessageDialog(null, "Name: " + name+ "\n" + "Phone: " +number          +"\n"     +       "Email: " + email);
    }

    public static void main(String[] args) {
        MyPhoneBook a[] = new MyPhoneBook[300];
        MyPhoneBook b = new MyPhoneBook();
        //final Integer[] sorted = ArrayUtils.toObject(MyPhoneBook);
        int i,n;
        n = Integer.parseInt(JOptionPane.showInputDi… total number:\n"));
        for(i=0;i<n;i++)
        {
            a[i] = new MyPhoneBook();
            a[i].input();
        }
        Arrays.sort(a);
        for(i=0;i<n;i++)
        {
            a[i].print();
        }
    }

    @Override
    public int compare(MyPhoneBook o1, MyPhoneBook o2) {
        return o1.number.compareTo(o2.number);
    }

    public int compareTo(MyPhoneBook o) {
        if(this.name.equals(o.name)) return this.number.compareTo(o.number);
        if(this.number.equals(o.number)) return this.email.compareTo(o.email);
        if(this.email.equals(o.email)) return this.name.compareTo(o.name);
        return 0;
    }
}

3 个答案:

答案 0 :(得分:1)

只需使用String#compareTo,它会按字典顺序比较两个字符串。比较基于字符串中每个字符的Unicode值。

public class MyPhoneBook implements Comparable<MyPhoneBook>{
    @Override
    public int compareTo(MyPhoneBook o) {
            int returnValue =0;
            if(o!=null){
                  returnvalue = this.name.compareTo(o.name);
                  if(returnValue==0){
                       returnValue = this.number.compareTo(o.number);
                       if(returnValue==0){
                              returnValue = this.email.compareTo(o.email);
                      }
                  }

            }
            return returnValue;
        }
}

答案 1 :(得分:1)

这里有几个问题:首先是你的比较实际上不是字典。例如,当名称相等时,您完全忽略比较逻辑中的电子邮件地址。第二个问题是您未能将比较器指定为Arrays.sort()的参数。

第一个问题:修复比较逻辑

如果你可以在你的代码中使用第三方库,那么处理这个问题的一个非常简洁的方法是使用ComparisonChain库中的Guava类(Google的核心Java库是开源的):

public int compareTo(MyPhoneBook o) {
  return ComparisonChain
      .start()
      .compare(name, o.name)
      .compare(email, o.email)
      .compare(number, o.number)
      .result();
 }

假设你不能这样做,这是正确的方法:

public int compareTo(MyPhoneBook o) {
   int nameComparison = name.compareTo(o.name);
   if (nameComparison != 0) {
     return nameComparison;
   }
   int emailComparison = email.compareTo(o.email);
   if (emailComparison != 0) {
     return emailComparison;
   }
   return number.compareTo(o.number);
}

第二个问题:使用比较器

调用Arrays.sort()

使用:

代替您当前对Arrays.sort()的调用
Arrays.sort(a, new PhoneBookComparator());

将PhoneBookComparator定义为单独的Comparator类。

答案 2 :(得分:0)

在发布代码时运行代码时,它会出现在

Exception in thread "main" java.lang.ClassCastException: ...
MyPhoneBook cannot be cast to java.lang.Comparable

这是因为你打电话

Arrays.sort(a);

Arrays.html#sort期望数组中包含的对象实现接口Comparable。尽管如此,你的课程仍然是Comparator

您应该将您的班级声明更改为以下

之一
public class MyPhoneBook implements Comparable<MyPhoneBook> {

然后删除

@Override
public int compare(MyPhoneBook o1, MyPhoneBook o2) {
    return o1.number.compareTo(o2.number);
}

或者

public class MyPhoneBook {

和排序调用

Arrays.sort(a, new Comparator<MyPhoneBook>() {
    @Override
    public int compare(MyPhoneBook o1, MyPhoneBook o2) {
        // TODO implment here your comapre logic
        return o1.number.compareTo(o2.number);
    }
});

修复后你会得到NullPointerException,因为行

Arrays.sort(a);

这是因为您传递了一个长度为300的数组,因此您不必将所有300个元素放入其中,因为您要求total number

你应该使用

Arrays.sort(a, 0, n);

这只排序了有数据的范围。请参阅javadoc