【问题标题】:Difference in passing an object to an arraylist (initializing once and more than once)将对象传递给数组列表的区别(初始化一次和多次)
【发布时间】:2014-09-21 16:40:07
【问题描述】:

这是我的主类MainClass,它有一个数组列表MyList。我为 ExtractClass [未显示] extract 创建了一个对象并将其添加到我的 MyList。还有另一个类 PressClass [未显示]

public class MainClass {
  public static void main(String[] args) {

    ArrayList<ExtractClass> MyList = new ArrayList<ExtractClass>();

    ExtractClass Extract = new ExtractClass();

    MyList.add(Extract);
    MyList.add(Extract);

    PressClass Press = new PressClass(); 
    Press.pressMethod(MyList);
  }
}

这是上述程序的另一个版本。我已经初始化了一个对象 Extract,然后添加到 MyList 并再次重复。

public class trailclass {
  public static void main(String[] args) {

    ArrayList<ExtractClass> MyList = new ArrayList<ExtractClass>();

    ExtractClass Extract;

    Extract = new ExtractClass();
    MyList.add(Extract);

    Extract = new ExtractClass();
    MyList.add(Extract);

    PressClass Press = new PressClass(); 
    Press.pressMethod(MyList);
  }
}

两个程序的输出相同。两者有什么区别?以上两个代码中的任何一个都违反了java的规则吗?作为开发者,更喜欢哪一段代码?

【问题讨论】:

  • 在您的第一段代码中,您正在添加相同的对象,而在第二段代码中,您正在实例化新对象

标签: java object arraylist


【解决方案1】:

这取决于您尝试实现的目标... 在第一个 sn-p 中,您将 same ExtractClass 实例两次添加到列表中,在第二个代码 sn-p 中,您将 2 个 不同 ExtractClass 实例添加到列表中。由于我不了解您的 ExtractClass 的内部结构,因此我可以确定哪些代码是“正确的”。

【讨论】:

    【解决方案2】:

    简单的答案是您正在创建两个对象,其中一个您不需要。但是,垃圾收集器不会销毁它,因为它位于 ArrayList MyList 中,因此对它的引用仍然可以访问。 在第一个示例中,同一对象被两次添加到 ArrayList 中。在第二个示例中,创建一个对象并将其添加到 ArrayList。之后,创建了一个新对象并将其添加到 ArrayList 中。对象可能具有相同的值(但是您创建了构造函数)但引用不同。

    如果您需要更多解释,请询问。

    【讨论】:

      【解决方案3】:

      两者有什么区别?

      第一个创建一个单个对象并将其两次添加到列表中

      在您创建 两个 不同的 (1) 对象并将每个对象添加 一次 到列表中的那一刻,这实际上是您在大多数情况下打算做的事情。

      以上两个代码有没有违反java规则?

      技术上不是。 List 允许同一个对象在其中出现多次。从语义上讲,这取决于您是否有意在列表中多次使用相同的对象。

      作为开发人员,更喜欢哪一段代码?

      一般来说,你的意思是有第二个版本。

      (1) 不同取决于您对hashCodeequals 的实现。基类Object 的默认值只是进行参考检查。所以不同的实例将不相等,因此不同。当您使用List#contains 方法时,您可以看到它的影响。根据您对前一种方法的实现以及传递给它的实例,您可能会得到不同的结果。

      【讨论】:

        【解决方案4】:

        提出的 2 个解决方案并不相同。第一个将同一个对象两次添加到列表中,而第二个将 2 个不同的实例添加到列表中。

        顺便说一句,在同一行初始化一个局部变量更紧凑,如果它是一个简单的对象创建,你应该更喜欢:

        ExtractClass Extract = new ExtractClass();
        

        另外请注意,如果您不使用局部变量,您可以简单地将其省略并直接添加到列表中:

        MyList.add(new ExtractClass());
        

        另外,按照惯例,变量名应以小写字母开头,类型(例如类名)应以大写字母开头。

        【讨论】:

          【解决方案5】:

          根据您当前的实施,这两个程序都可以工作,因为您正在添加对象 new ExtractClass() 在列表中具有默认实现。第一个程序将同一对象添加两次,而第二个程序将 2 个不同的实例添加到列表中。

          如果您遇到ExtarctClass 构造函数接受某些参数的情况,比如说File destDir,您将剩下第二个选项,因为您可能必须为不同的对象提供不同的 destDir

          上面说你的第二个程序如下所示

          public class trailclass {
            public static void main(String[] args) {
          
              ArrayList<ExtractClass> MyList = new ArrayList<ExtractClass>();
          
              ExtractClass Extract;
          
              Extract = new ExtractClass(new File("c:\temp"));
              MyList.add(Extract);
          
              Extract = new ExtractClass(new File("c:\temp"));
              MyList.add(Extract);
          
              PressClass Press = new PressClass(); 
              Press.pressMethod(MyList);
            }
          }
          

          这可以进一步写成如下

          public class trailclass {
            public static void main(String[] args) {
              ArrayList<ExtractClass> MyList = new ArrayList<ExtractClass>();
              MyList.add(new ExtractClass(new File("c:\temp")));
              MyList.add(new ExtractClass(new File("c:\temp")));
          
              PressClass Press = new PressClass(); 
              Press.pressMethod(MyList);
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-05-13
            • 1970-01-01
            • 2023-03-23
            • 1970-01-01
            • 1970-01-01
            • 2015-08-03
            • 2021-03-02
            • 2020-02-03
            相关资源
            最近更新 更多