java comparable null_关于java:关于null的Comparable和Comparator契约

Comparable合同规定e.compareTo(null)必须抛出NullPointerException。

从API:

Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.

另一方面,Comparatorapi在比较null时没有提到需要发生什么。考虑下面的一个泛型方法的尝试,该方法使用Comparable,并为它返回一个Comparator,该方法将null作为最小元素。

static > Comparator nullComparableComparator() {

return new Comparator() {

@Override public int compare(T el1, T el2) {

return

el1 == null ? -1 :

el2 == null ? +1 :

el1.compareTo(el2);

}

};

}

这使我们可以执行以下操作:

List numbers = new ArrayList(

Arrays.asList(3, 2, 1, null, null, 0)

);

Comparator numbersComp = nullComparableComparator();

Collections.sort(numbers, numbersComp);

System.out.println(numbers);

//"[null, null, 0, 1, 2, 3]"

List names = new ArrayList(

Arrays.asList("Bob", null,"Alice","Carol")

);

Comparator namesComp = nullComparableComparator();

Collections.sort(names, namesComp);

System.out.println(names);

//"[null, Alice, Bob, Carol]"

所以问题是:

这是可以接受的使用Comparator,还是违反了比较null和丢弃NullPointerException的不成文规则?

对包含null元素的List进行排序是一个好主意,还是这是设计错误的一个确定标志?

请注意,有些人在编译这段代码时遇到了问题:javac中有一个bug,但它在Eclipse中编译并运行!!!!stackoverflow.com/questions/2858799/…

Comparable不允许null仅仅因为:

a.compareTo(b) == -b.compareTo(a)

对于所有对象a和b,其中!a.equals(b)。更具体地说:

a.equals(b) ? b.equals(a) && a.compareTo(b) == 0 &&

b.compareTo(a) == 0 && a.hashCode() == b.hashCode()

: !b.equals(a) && a.compareTo(b) != 0 &&

a.compareTo(b) == -b.compareTo(a)

必须对true进行评估,以满足相关合同。

所以不允许使用null,因为你不能这样做:

null.compareTo(a)

Comparator更加灵活,因此处理null是一个具体的实施问题。是否支持它取决于您希望您的Comparator做什么。

a.b == -b.a测试是令人信服的,但我更喜欢API的论点:Comparable定义了类实例的自然排序,而null只是不是任何类的实例。不过,你会首先在List中提到null吗?我希望那不是[subjective]。

(这样的公式a.compareto(b)=-b.compareto(a)不一定对每种类型都正确。compareTo()的返回值不需要表示两个对象的任何字段的差异。虽然CompareTo()经常被编程,但这不是一个好主意!-计算的差异可能溢出,然后导致错误的正/负值。(最好从compareto()中返回-1、0或1。-这不是偷偷摸摸,而是正确的。))

Is it ever a good idea to even have to sort a List containing null elements, or is that a sure sign of a design error?

从概念上讲,空意味着"没有",在列表中放置任何东西对我来说都是奇怪的。此外,Java列表约定声明

Some list implementations have restrictions on the elements that they may contain. For example, some implementations prohibit null elements

因此,甚至不需要支持Java元素来支持空元素。综上所述,如果您没有很好的理由将空值放入一个列表中,那么就不要这样做,如果这样做了,那么就测试它是否实际按预期工作。

+1.抓到List中的null支持甚至不是强制性的。

Is it ever a good idea to even have to

sort a List containing null elements,

or is that a sure sign of a design

error?

好吧,列表包含空对象可能没有意义,但是您的列表可能包含一个"业务对象",您可以根据业务对象的不同属性进行排序,其中一些属性可能包含空值。

Is this an acceptable use of a

Comparator

BeanComparator允许您对业务对象中的属性进行排序,即使该属性包含空值,所以我不得不说它是Comparator的一种可接受的用法。

哪个"BeanComparator"?这不是JDK的一部分,我们不能指望它在这方面证明任何东西。

@Ymajoros,Which"BeanComparator"?链接中找到的那个。

这不是JDK的一部分…除了是一个坏主意(不安全、重构中断等)。

@伊马乔罗斯,JDK跟什么有关系?通过编写可重用代码来解决问题。这是如何不安全的?它是如何在重构中破坏的?你在重构什么?这个类只是一个您可以使用的工具,所以您不需要每次进行排序时都编写一个定制的比较器。

为什么它是一个"可接受的比较器使用",因为有人在某个地方写了一个BeanComparator(无论如何这是一个坏主意)?Comparator有一个契约,这个AlienBeanComparator的东西不一定要观察它,你不能指望它来证明比较空属性是可以的。

开头不安全,重命名字段时它将中断;编译不检查它是否工作,而是在运行时中断;很难找到字段的用法等。

@伊马约洛斯,-伊多克斯1〔9〕这有什么关系?它只是比较同一类型的两个对象,不管它们是什么类型。it will break whenever you rename the field和您多久重命名一个字段?compilation doesn't check if it's working, it will break at runtime when used insteadJDK中有许多运行时异常。为什么这是个问题?通常在将类转移到生产环境之前对它进行测试。difficult to find the field's usages,不知道那是什么意思。它只是一个比较器,您不关心字段的用法,只需要比较值。

Comparator has a contract只返回一个指示大于、小于或相等的值。如果您有一些特殊的比较规则,那么就创建一个定制的比较器。我不是建议在所有情况下都使用这个。我还注意到,它效率很低,因此不应用于大型应用,但在小型应用中可以令人满意。you can't count on it for proving that comparing null attributes is ok有处理空值的默认逻辑。同样,如果它不满足您的需求,那么创建一个定制的比较器。这只是一门选修课。

#camicker最好是让安全代码在编译时而不是运行时如预期那样失败。使用字符串引用字段绝对是一种糟糕的做法。但不是这里的主题,如果需要的话,我建议我们继续聊天。

#事实上,比较器的契约是对原始问题的正确答案(它不仅仅是返回-1/0/1,参见javadoc)。引用这个BeanComparator并不能证明与原始合同有关的任何东西,而BeanComparator可以执行或者不执行这个合同。如果需要的话,我建议我们继续进行聊天。

@伊马乔罗斯同意,如果你是在抱怨的话,这不是对最初问题的一个很好的回答。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值