【问题标题】:Java: Different outputs when add/remove short and integer elements in a SetJava:在集合中添加/删除短元素和整数元素时的不同输出
【发布时间】: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

【问题讨论】:

    标签: java integer set short


    【解决方案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。

      【讨论】:

        猜你喜欢
        • 2015-08-13
        • 2022-10-23
        • 2015-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 2016-06-01
        • 2020-08-12
        相关资源
        最近更新 更多