Java:在集合中添加/删除短元素和整数元素时的不同输出

Posted

技术标签:

【中文标题】Java:在集合中添加/删除短元素和整数元素时的不同输出【英文标题】:Java: Different outputs when add/remove short and integer elements in a Set 【发布时间】:2012-11-13 17:57:10 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

表达式i - 1 的类型是int,因为整数算术表达式中的所有操作数都至少扩展为intSet&lt;Short&gt; 具有 add(Short)remove(Object),因此在 remove 调用中不需要强制转换/自动装箱。因此,您试图从一组Shorts 中删除Integers。

请注意,由于这个原因,声明Set&lt;Number&gt; 几乎没有意义:

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,魔法就会消失并抛出一个 ClassCastException,从而放弃了窍门。

在内心深处,这个问题与相等是对称关系这一事实有关,它不能区分右手边和左手边。这些语义是 Java 的单一调度方法无法实现的。

【讨论】:

无论我执行 a.add((short)i) 还是 a.add(i) ...我的输出都保持为 100。 当然。 Short 变量不需要转换运算符。我的原始答案是指您的原始问题,我通过引入short 转换解决了这个问题,而您以不同的方式解决了它。 这不是因为 1 是一个 int,而是因为赋值运算符右侧的算术表达式默认计算为 int。例如。短 i = 1;短 j = i + i;不会编译。 @RobertBain 但是这里没有任务。你的意思是说 all 算术表达式至少和int 一样宽吗?因为那是正确的。 @MarkoTopolnik 这正是我想说的,但出于某种原因描述了我自己的例子而不是答案中的例子。很高兴你明白我的意思!【参考方案2】:

第一个代码 sn-p 从 IntegersHashSet 中删除除 99 之外的所有数字,因为 98 是它删除的最后一个数字。

第二个代码 sn-p 试图从 HashSetShorts 中删除 Integer,因此,它不会删除任何元素。

在第一个代码 sn-p 中,add(i) 语句中的 int 自动转换为 Integer

在第二个代码 sn-p 上,如果您执行了以下操作:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于Java:在集合中添加/删除短元素和整数元素时的不同输出的主要内容,如果未能解决你的问题,请参考以下文章

java中在for循环中remove元素时的陷阱

java集合类

set集合——无序的不重复元素序列

如何用C++实现一个整数类的集合??

java 中如何 找出两个集合中的不重复的元素

【java】集合List里面的元素排列