Java 无法理解Arrays.sort()功能

Java 无法理解Arrays.sort()功能,java,nullpointerexception,Java,Nullpointerexception,我是Java新手,我试图理解Comparator接口。 我尝试了以下代码: package comparator; import java.io.*; import java.util.*; public class comparator { public static void main(String args[]){ bankAccount[] ba=new bankAccount[500]; ba[0]=new bankAccount(50);

我是Java新手,我试图理解Comparator接口。 我尝试了以下代码:

package comparator;

import java.io.*;
import java.util.*;

public class comparator {
    public static void main(String args[]){
        bankAccount[] ba=new bankAccount[500];
        ba[0]=new bankAccount(50);
        ba[1]=new bankAccount(90);
        ba[2]=new bankAccount(20);
        Comparator c=new comparing();
        System.out.println(c.compare(ba[0], ba[1]));
        Arrays.sort(ba, c);
    }
}

class bankAccount{
    public bankAccount(double bal){
        balance=bal;
    }
    public double balance;
}

class comparing implements Comparator{
    public int compare(Object first, Object second){
        bankAccount ba1=(bankAccount)first;
        bankAccount ba2=(bankAccount)second;
        int retval;
        if(ba1.balance<ba2.balance){
            retval=-1;
        }
        else if(ba1.balance>ba2.balance){
                retval=1;
            }
        else{
            retval=0;
        }
        return retval;
    }
}

我能知道是什么错误吗。我应该如何使用Arrays.sort()方法。任何帮助都将不胜感激

main
方法中,您声明了一个500长度的数组,但只初始化了3个元素,因此其中497个元素
null
。这会在比较器中造成问题,因为比较器是为许多对元素调用的,包括一些
null
元素


尝试修改
main
方法,使其仅声明和初始化3长度数组,然后编译并再次运行。也许您的比较器中确实存在问题,但至少让我们消除这个明显的问题,并尝试在所有元素均为非空的情况下进行排序。问题在于,您只填充了500个条目数组的前3个条目,排序方法将遍历这些条目并进行比较,直到满足条目4,它为null,当它试图调用其
compareTo(..)
方法时抛出NPE


您可以通过填充数组或将其长度设置为3来修复它。

将bankAccount数组的大小更改为3

若任何数组元素为null,若您的比较器不支持null,它将抛出null指针异常

下面的代码将使用数组大小500,因为比较器处理空情况

    if (first == null || second == null)
    {
        return 0;
    }
修改后的原始类代码以修复开始(查看比较类中的更改):

import java.io.*;
导入java.util.*;
公共类比较器{
公共静态void main(字符串参数[]){
银行账户[]ba=新银行账户[500];
ba[0]=新银行账户(50);
ba[1]=新银行账户(90);
ba[2]=新银行账户(20);
比较器c=新的比较();
System.out.println(c.compare(ba[0],ba[1]);
数组。排序(ba,c);
}
}
类别银行帐户{
公共银行账户(双倍余额){
余额=余额;
}
公共双平衡;
}
类比较器{
公共整数比较(对象第一,对象第二){
银行账户ba1=(银行账户)第一;
银行账户ba2=(银行账户)第二;
内部检索;
if(first==null | | second==null)
{
返回0;
}
if(ba1.余额Ba2.余额){
retval=1;
}
否则{
retval=0;
}
返回返回;
}
}

除了Platnium Azure前面的答案之外,您还应该在
Comparator
子类中使用泛型,如下所示:

class comparing implements Comparator<bankAccount>
{
...
    @Override
    public int compare(bankAccount first, backAccount second)
    {
    ...
    }

    @Override
    public boolean equals(Object obj)
    {
    ...
    }
...
}
类比较实现比较器
{
...
@凌驾
公共整数比较(银行帐户第一,后台帐户第二)
{
...
}
@凌驾
公共布尔等于(对象obj)
{
...
}
...
}

这将强制使用您的
比较
类仅用于对
银行账户
实例进行排序。

您的数组未完全初始化,如果您不想初始化它,请更改
比较

class comparing implements Comparator{
public int compare(Object first, Object second){
    bankAccount ba1=(bankAccount)first;
    bankAccount ba2=(bankAccount)second;
    int retval;
    if (ba1==null || ba2 == null) {
        retval=0; // return what you want if bankAccount is null.
    }
    else if(ba1.balance<ba2.balance){
        retval=-1;
    }
    else if(ba1.balance>ba2.balance){
            retval=1;
        }
    else{
        retval=0;
    }
    return retval;
}
}
类比较实现比较器{
公共整数比较(对象第一,对象第二){
银行账户ba1=(银行账户)第一;
银行账户ba2=(银行账户)第二;
内部检索;
if(ba1==null | | ba2==null){
retval=0;//如果bankAccount为空,则返回所需内容。
}
否则如果(ba1.余额Ba2.余额){
retval=1;
}
否则{
retval=0;
}
返回返回;
}
}

您应该在
比较
类中执行某种
null
检查。您还应该检查
比较
类中的
第一个
第二个
对象,以确保它们是
银行账户
对象。您不想将它们自动转换为
bankAccount
对象。请参考以下问题以获得良好的示例和解释:非常感谢。非常感谢你们的帮助。第一次正确地实现了
比较器,做得很好。:-)我很高兴你喜欢这种学习经历!:-)您应该查看其他一些答案,以了解将来要遵循的其他最佳实践(例如,执行
null
检查或检查实例是否属于正确的类)。此答案存在多个错误。首先,您希望
实现
比较器,而不是
扩展它,因为它是一个接口。另外,在您的示例中根本没有使用泛型。给定您的代码,您基本上是说
比较器
属于
银行账户
类型。如果它真的是泛型的,那么它看起来就像是
Comparator
,还有一些其他的变化,但这不是重点。@Franklin:想详细说明一下这些是什么吗?我发现了一个关于类型擦除是如何工作的问题,在大括号前面有一些轻微的惰性,但是我缺少了什么?关于
实现的部分是正确的,我在那里犯了一个错误。我真的不知道你所说的泛型部分是什么意思,你能解释一下问题出在哪里吗?@SimonT要使这个完全泛型,你必须做一些类似于
class Comparing implements Comparator{…}
,它读的是
Comparator
类型的
t
,它是泛型的<代码>类比较实现了Comparator{…}
是一个类型为
bankAccount
Comparator
,它不是通用的,因为它只适用于
bankAccount
对象。Franklin,我认为这只是一个沟通错误的问题。我的意图是让
比较
只接受
银行账户
实例,因为他提供的代码只有在给定的
对象
s被证明是
银行账户
s时才起作用。我想说的是Java泛型的一些用法(如
class comparing implements Comparator<bankAccount>
{
...
    @Override
    public int compare(bankAccount first, backAccount second)
    {
    ...
    }

    @Override
    public boolean equals(Object obj)
    {
    ...
    }
...
}
class comparing implements Comparator{
public int compare(Object first, Object second){
    bankAccount ba1=(bankAccount)first;
    bankAccount ba2=(bankAccount)second;
    int retval;
    if (ba1==null || ba2 == null) {
        retval=0; // return what you want if bankAccount is null.
    }
    else if(ba1.balance<ba2.balance){
        retval=-1;
    }
    else if(ba1.balance>ba2.balance){
            retval=1;
        }
    else{
        retval=0;
    }
    return retval;
}
}