【问题标题】:Why does Java allow arrays of size 0?为什么Java允许大小为0的数组?
【发布时间】:2011-06-04 11:46:50
【问题描述】:

java 中的数组是固定长度的。那么为什么 Java 允许大小为 0 的数组呢?

String[] strings = new String[0];

【问题讨论】:

    标签: java arrays


    【解决方案1】:

    它表示它是空的。 IE。您可以循环遍历它,就好像它有项目并且没有结果发生:

    for(int k = 0; k < strings.length; k++){
       // something
    }
    

    从而避免了检查的需要。如果有问题的数组是null,则会发生异常,但在这种情况下,它什么也不做,这可能是合适的。

    【讨论】:

    • 当有函数test()时调用函数test(Object... objects)也很有用
    【解决方案2】:

    为什么 Java 允许大小为 1 的数组?将单个值包装在数组中不是很没用吗?如果 Java 只允许大小为 2 或更大的数组,那还不够吗?

    是的,我们可以传递 null 而不是空数组和单个对象或基元而不是 size-one-matrix。

    但是有一些很好的论据反对这种限制。我个人的主要论点:

    限制太复杂,没有必要

    要将数组限制为 [1..INTEGER.MAX_INT] 的大小,我们必须添加 许多额外的边界检查,(同意 Konrads 评论) 转换逻辑和方法重载到我们的代码。从允许的数组大小中排除 0(也可能是 1)不会节省成本,它需要额外的努力并对性能产生负面影响。

    数组模型向量

    数组是一个很好的向量数据模型(数学,不是 Vector 类!)。当然,数学中的向量可能是零维的。这在概念上不同于不存在。


    旁注 - (char-)array 的突出包装是 String 类。不可变的String 实现了空数组的概念:它是空字符串 ("")。

    【讨论】:

    • 我不相信你的限制论点。 Java(与例如 C 不同)已经需要检查负数。此检查可以轻松适应 0(只需将 &gt;= 0 更改为 &gt; 0)。但是你当然是对的,所以添加这个限制是没有意义的。
    • 循环迭代参数在我看来似乎更好:“for(int k = 0; k
    • 不,这不是 我的 意见,因为在没有零大小数组的世界中,空字符串(基于 char 数组)根本不存在,所以不需要考虑循环中的空数组。这个迭代参数是一个非常实际的副作用。在那个世界中,一个数组至少有一个条目。 (或者两个,因为:为什么需要一个数组来存储一项?)
    • 对负索引和过高索引的检查是相同的检查:负索引总是无符号的,不小于数组的长度
    【解决方案3】:

    有时返回一个大小为零的数组比返回 null 更友好。

    【讨论】:

    • 这被称为“空对象”模式。
    【解决方案4】:

    考虑一下(对中午答案的更详细解释):

    public String[] getStrings() {
     if( foo ) {
      return null;
     } else {
      return new String[] {"bar, "baz"};
     }
    }
    
    String[] strings = getStrings();
    if (strings != null) {
     for (String s : strings) {
      blah(s);
     }
    }
    

    现在比较一下:

    public String[] getStrings() {
     if( foo ) {
      return new String[0];
     } else {
      return new String[] {"bar, "baz"};
     }
    }
    
    // the if block is not necessary anymore
    String[] strings = getStrings();
    for (String s : strings) {
     blah(s);
    }
    

    这(返回空数组而不是空值)实际上是 Java API 设计界的最佳实践。

    此外,在 Java 中,您可以将列表(例如 ArrayList)转换为数组,只有将空列表转换为空数组才有意义。

    【讨论】:

      【解决方案5】:

      与 C++ 相同,它允许在没有数据时进行更清晰的处理。

      【讨论】:

        【解决方案6】:

        零长度数组可能有用的另一种情况: 要返回一个包含列表中所有元素的数组:

        <T> T[ ] toArray(T[ ] a)
        

        零长度数组可用于将数组的类型传递给此方法。例如:

        ClassA[ ] result = list.toArray(new ClassA[0]);
        

        零长度数组仍然是一个包含零元素的 Object 实例。

        【讨论】:

          【解决方案7】:

          我能想到的一个空数组非常有用的情况是在不允许 null 的情况下使用它而不是 null。一个可能的例子是数组的 BlockingQueue。当您想向读取端发出输入结束信号时,您会怎么做?发送空值似乎是一个显而易见的选择,但问题是 BlockingQueue 不接受空值。您可以将数组包装在一个带有“boolean last;”类字段的类中,但这有点矫枉过正。发送一个空(零大小)数组似乎是最合理的选择。

          【讨论】:

            【解决方案8】:

            零长度数组有用的另一种情况是复制二维数组时。我会写:

            public int[][] copyArray(int[][] array){
                 int[][] newArray = new int[array.length][0];
                 for(int i=0;i<array.length;i++){
                     newArray[i] = array[i];
                 }
                 return newArray;
            

            由于数组中的每个数组引用都被覆盖,将它们初始化为对零长度数组的引用是最有效的。

            【讨论】:

            • 这是相当具有误导性的代码。如果某人有一个二维整数数组a 并说b = copyArray(a);,则更改a 指向的数据将更改b 指向的数据。这听起来不像是我的副本。
            【解决方案9】:

            长度为 0 的 byte[]char[] 可以表示空的 String,这与 null 不同。从字符串中获取字节或字符作为数组(使用String 类的getBytes()getChars() 等),反之亦然,从byte[]char[] 形成Strings 是很常见的.例如,对于自定义编码,字符串的解码。

            【讨论】:

            • 他们使用 0 大小的数组,因为它很有用。它没有用,因为它们使用 0 大小的数组。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-08-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-18
            • 1970-01-01
            • 2014-09-14
            相关资源
            最近更新 更多