3

我不确定如何问这个问题。但是,这两行代码有什么不同呢?

Set<Integer> a = new HashSet<Integer>();
for (int i = 0; i < 100; i++) {
    a.add(i);
    a.remove(i - 1);
}

System.out.println(a.size());

我希望99是输出

输出为1


Set<Short> a = new HashSet<Short>();
for (Short i = 0; i < 100; i++) {
    a.add(i);
    a.remove(i - 1);
}

System.out.println(a.size());

我希望99是输出

输出为100

4

3 回答 3

11

表达式的类型i - 1int因为整数算术表达式中的所有操作数都扩展为至少int. Set<Short>add(Short),因此通话中remove(Object)不需要强制转换/自动装箱。remove因此,您试图Integer从一组s 中删除Shorts。

请注意,由于这个原因,声明 a 几乎没有意义Set<Number>

final Set<Number> ns = new HashSet<>();
final short s = 1;
ns.add(s);
ns.add(s+0);
ns.add(s+0L);
System.out.println(ns); // prints [1, 1, 1]

作为奖励回合,如果您将 set 实现更改为TreeSet,魔法就会消失并抛出 a ClassCastException,从而放弃技巧。

本质上,这个问题与相等是对称关系这一事实有关,它不能区分右手边和左手边。这些语义用 Java 的单调度方法是不可能实现的。

于 2012-11-13T18:02:33.437 回答
3

第一个代码片段从所有数字中删除,除了HashSet因为是它删除的最后一个数字。Integers9998

第二个代码片段试图Integer从 aHashSet中删除一个Shorts,因此,它不会删除任何元素。

在第一个代码片段中,语句add(i)中的int自动转换为Integer.

在第二个代码片段中,如果您执行了以下操作:

Set<Short> a = new HashSet<Short>();
for (Short i = 0; i < 100; i++) {
     a.add(i);
     a.remove(i);
}

它将删除所有元素,因为您添加和删除了Short. 但是,因为您正在尝试删除i - 1,它将转换i - 1Integer. 因此,试图Integer从 的 HashSet 中删除一个Shorts,这实际上导致没有数字被删除。

于 2012-11-13T18:02:38.860 回答
2

你不能在不强制转换的情况下从 Set of shorts 中删除 Integer。

于 2012-11-13T18:03:49.283 回答