Java 无法理解Arrays.sort()功能
我是Java新手,我试图理解Comparator接口。 我尝试了以下代码: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);
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;
}
}