热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA:Arraylist覆盖之前的条目[复制]-JAVA:Arraylistoverwritespreviousentry[duplicate]

Thisquestionalreadyhasananswerhere:这个问题在这里已有答案:WhydoesmyArrayListcontainNco

This question already has an answer here:

这个问题在这里已有答案:

  • Why does my ArrayList contain N copies of the last item added to the list? 4 answers
  • 为什么我的ArrayList包含添加到列表中的最后一项的N个副本? 4个答案

Beginner, be kind.

初学者,善待。

Whenever I add to the arraylist through the "Add Person", it overwrites the previous entry. So when I run sort, I then get two of the exact same entries which is whichever was typed in last. How do I fix this? What do I do?

每当我通过“添加人”添加到arraylist时,它会覆盖前一个条目。因此,当我运行sort时,我会获得两个完全相同的条目,这些条目是最后输入的。我该如何解决?我该怎么办?

Here is my class file:

这是我的班级文件:

import java.util.Calendar;
import java.util.Date;
import java.text.*;

public class Person implements Comparable {

    private static int totalNumber;

    public static int getTotal() {

        // Returns total number of employees
        return totalNumber;
    }

    private String fName;
    private String lName;
    private Date lastModified;
    private String address;
    private String city;
    private String state;
    private String zip;
    private String phone;

    public Person(String fName, String lName, String address, String city,
            String state, String zip, String phone) {
        this.fName = fName;
        this.lName = lName;
        this.address = address;
        this.city = city;
        this.state = state;
        this.zip = zip;
        this.phOne= phone;
        Calendar calobj = Calendar.getInstance();
        this.lastModified = calobj.getTime();
    }

    public String getfName() {
        return this.fName;
    }

    public void setfName(String fName) {
        this.fName = fName;
    }

    public String getlName() {
        return this.lName;
    }

    public void setlName(String lName) {
        this.lName = lName;
    }

    public Date getLastModified() {
        return this.lastModified;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

    public String getAddress() {
        return this.address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return this.city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return this.state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return this.zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhone() {
        return this.phone;
    }

    public void setPhone(String phone) {
        this.phOne= phone;
    }

    @Override
    public String toString() {
        DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
        return "\n First Name= " + fName + "\n Last Name= " + lName
                + "\n Address= " + address + "\n City= " + city + "\n State= "
                + state + "\n Zip= " + zip + "\n PhOne= " + phone
                + "\n Last Modified= " + df.format(lastModified);
    }

    @Override
    public int compareTo(Object other) {
        // TODO Auto-generated method stub
        return this.lName.compareToIgnoreCase(((Person) other).lName);

    }

}

Here is my test file:

这是我的测试文件:

import java.util.*;

public class testAddressBook {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ArrayList addressBook = new ArrayList();
        Person newPerson = new Person(null, null, null, null, null, null, null);

        @SuppressWarnings("resource")
        Scanner sc = new Scanner(System.in);

        boolean switcher = true;
        do {
            System.out.println("\n\tAddress Book Menu");
            System.out.println("\n\t\tEnter A to (A)dd Person ");
            System.out.println("\t\tEnter D to (D)elete Person");
            System.out.println("\t\tEnter M to (M)odify Person");
            System.out.println("\t\tEnter S to (S)earch Address Book ");
            System.out.println("\t\tEnter L to (L)ist ALL (sorted) ");
            System.out.println("\t\tEnter Q to Quit");
            System.out.print("\n\tPlease enter your choice: ");
            char choice = sc.nextLine().toUpperCase().charAt(0);

            while ((choice != 'A') && (choice != 'D') && (choice != 'M')
                    && (choice != 'S') && (choice != 'L') && (choice != 'Q')) {
                System.out
                        .println("Invalid choice!  Please select (A)dd, (D)elete, (M)odify, (S)earch, (L)ist or (Q)uit: ");
                choice = sc.nextLine().toUpperCase().charAt(0);
            }

            switch (choice) {
            case 'A':
                System.out.println("\nTo add a person, follow the prompts.");

                System.out.print("\nEnter First Name: ");
                newPerson.setfName(sc.nextLine());

                System.out.print("\nEnter Last Name: ");
                newPerson.setlName(sc.nextLine());

                System.out.print("Enter Address: ");
                newPerson.setAddress(sc.nextLine());

                System.out.print("Enter City: ");
                newPerson.setCity(sc.nextLine());

                System.out.print("Enter State: ");
                newPerson.setState(sc.nextLine());

                System.out.print("Enter Zip: ");
                newPerson.setZip(sc.nextLine());

                System.out.print("Enter Phone Number: ");
                newPerson.setPhone(sc.nextLine());

                addressBook.add(newPerson);

                System.out
                        .println("\nYou have successfully added a new person!");

                break;

            case 'D':

                break;
            case 'M':

                break;
            case 'S':
                Collections.sort(addressBook);

                for (int i = 0; i 

5 个解决方案

#1


You need to instantiate a new Person in the loop. For example declare:

您需要在循环中实例化一个新Person。例如声明:

Person newPerson;

And then in while loop instantiate it:

然后在while循环实例化它:

switch (choice) {
        case 'A' :      
            System.out.println("\nTo add a person, follow the prompts.");       
            newPerson = new Person(null, null, null, null, null, null, null);
 .... so on

If you also instantiate it out of the loop as well it leads to creation of one extra object.

如果你也将它从循环中实例化,那么它会导致创建一个额外的对象。

#2


You have to create a new instance of Person for every iteration of the loop. Otherwise, you are just updating the same Person all over again.

您必须为循环的每次迭代创建一个Person的新实例。否则,您只是重新更新同一个人。

Move this line into the do loop:

将此行移动到do循环中:

Person newPerson = new Person(null, null, null, null, null, null, null);

Over even better, make a private method that returns a new Person and have something like

甚至更好,制作一个私有方法,返回一个新的Person,并有类似的东西

 addressBook.add(readNewPerson(sc));
 System.out.println("\nYou have successfully added a new person!");

#3


You create your Person only one times:

您只创建一次您的Person:

 Person newPerson = new Person(null, null, null, null, null, null, null);

And you override the properties in every loop. You have to create a new person in your loop:

并且您在每个循环中覆盖属性。您必须在循环中创建一个新人:

   do {
        System.out.println("\n\tAddress Book Menu");
        System.out.println("\n\t\tEnter A to (A)dd Person ");
        System.out.println("\t\tEnter D to (D)elete Person");
        System.out.println("\t\tEnter M to (M)odify Person");
        System.out.println("\t\tEnter S to (S)earch Address Book ");
        System.out.println("\t\tEnter L to (L)ist ALL (sorted) ");
        System.out.println("\t\tEnter Q to Quit");
        System.out.print("\n\tPlease enter your choice: ");
        char choice = sc.nextLine().toUpperCase().charAt(0);


        while ((choice != 'A') && (choice != 'D') && (choice != 'M')  && (choice != 'S') && (choice != 'L')&& (choice != 'Q')) {
            System.out.println("Invalid choice!  Please select (A)dd, (D)elete, (M)odify, (S)earch, (L)ist or (Q)uit: ");
            choice = sc.nextLine().toUpperCase().charAt(0);
        }


        switch (choice) {
        case 'A' :      
            System.out.println("\nTo add a person, follow the prompts.");       
            Person newPerson = new Person(null, null, null, null, null, null, null);
 ....

#4


           `Person newPerson = new Person();//define a default constructor
             . . . . 
            System.out.print("Enter Phone Number: ");
            newPerson.setPhone(sc.nextLine());

            addressBook.add(newPerson);`

You need to create a new person in side a loop and set his attributes, finally add the person to list.

您需要在循环中创建一个新人并设置其属性,最后将该人员添加到列表中。

#5


You are reusing the newPerson object over and over, just rewriting the internal fields. In Java an object (rather than primitive) variable is a named reference to an object, so every time you do addressBook.add(newPerson) you are adding the same object to the list (this is allowed because it's not a Set). You are not copying newPerson into the list, you are just making the nth position in the list point to newPerson.

您正在重复使用newPerson对象,只需重写内部字段。在Java中,对象(而不是原始)变量是对象的命名引用,因此每次执行addressBook.add(newPerson)时,都会将相同的对象添加到列表中(这是允许的,因为它不是Set)。您没有将newPerson复制到列表中,只是将列表中的第n个位置指向newPerson。

The minimal change would be to move the object constructor call as Thilo suggests, but I strongly agree with his further suggestion that you should be using a dedicated method for each case. In that case, your whole problem disappears neatly due to scope of the local variable. In general you should structure your programs so that they make sense and are readable (rather than being a monolithic main procedure) and as a direct consequence all sorts of bugs just never happen.

最小的改变是移动对象构造函数调用Thilo建议,但我非常同意他的进一步建议,即你应该为每个案例使用专用方法。在这种情况下,由于局部变量的范围,整个问题会整齐地消失。一般来说,你应该构建你的程序,使它们有意义和可读(而不是一个单一的主程序),直接的结果是各种各样的错误永远不会发生。

See also:

What's the difference between passing by reference vs. passing by value?

传递参考与传递值之间有什么区别?


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
author-avatar
我户口名字被占用了_402
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有