有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在没有ArrayList的Java中返回数组中的搜索结果

我在不知道可以使用ArrayList的情况下,开始在数组中实现一个简单的hw任务搜索。我意识到它有一些bug,并认为在使用ArrayList之前,我仍然会尝试知道我的bug是什么。我基本上有一个类,可以在其中添加、删除或从数组中搜索

public class AcmeLoanManager 
{
    public void addLoan(Loan h)
    {
        int loanId = h.getLoanId();
        loanArray[loanId - 1] = h;
    }


    public Loan[] getAllLoans()
    {
        return loanArray;
    }


    public Loan[] findLoans(Person p)
    {
        //Loan[] searchedLoanArray = new Loan[10]; // create new array to hold searched values
        searchedLoanArray = this.getAllLoans(); // fill new array with all values

        // Looks through only valid array values, and if Person p does not match using Person.equals()
        // sets that value to null.
        for (int i = 0; i < searchedLoanArray.length; i++) {
            if (searchedLoanArray[i] != null) {
                if (!(searchedLoanArray[i].getClient().equals(p))) {
                    searchedLoanArray[i] = null;
                }
            }
        }
        return searchedLoanArray;
    }

    public void removeLoan(int loanId)
    {
        loanArray[loanId - 1] = null;
    }

    private Loan[] loanArray = new Loan[10]; 
    private Loan[] searchedLoanArray = new Loan[10]; // separate array to hold values returned from search
}

在测试这个时,我认为它是有效的,但我认为我在搜索后覆盖了我的成员变量。我最初以为我可以在这个方法中创建一个新的Loan[]并返回它,但这似乎不起作用。然后我想我可以有两个数组。一个不会改变,另一个只针对搜索的值。但我认为我不理解一些东西,比如浅薄的复制和深层的复制


共 (4) 个答案

  1. # 2 楼答案

    getAllLoans的返回值覆盖了searchedLoanArray引用,这意味着loanArray和searchedLoanArray都指向同一个底层数组。尝试将searchedLoanArray设置为局部变量,然后使用数组。复印件。如果您试图不在家庭作业中使用标准函数,请手动创建与loanArray大小相同的新Loan数组,然后循环并复制这些值

  2. # 3 楼答案

    你可以这样重写:

    public Loan[] findLoans(Person p)
    {
        Loan[] allLoans = this.getAllLoans();
        System.arraycopy(allLoans, searchedLoanArray, 0, 0, allLoans.length); // fill new array with all values
    
        // remainder of method the same
    

    }

    但就目前而言,该准则仍存在一些问题:

    1. 贷款的最大数量取决于数组的大小。当您切换到List<Loan>时,可以避免这个问题
    2. 使用id作为索引意味着必须仔细生成id。如果Id来自数据库,您可能会发现列表试图分配大量内存来调整自身大小以匹配Id。您最好使用地图,那么地图的大小基于贷款的数量,而不是贷款的Id
    3. 随着人数和贷款的增加,搜索时间也会增加。通过使用地图>;,您可以将搜索时间减少到一个常数(无论有多少人);,这样就可以快速查找与此人相关的贷款

    以下是一个有以下更改的版本:

       class AcmeLoanManager 
       {
          public void addLoan(Loan l)
          {
             Person client = l.getClient();
             List<Loan> loans = clientLoans.get(l);
             if (loans==null)
             {
                loans = new ArrayList();
                clientLoans.put(client, loans);
             }
             loans.add(l);
             allLoans.put(l.getLoanId(), l);
          }
    
          public void removeLoan(int loanId)
          {         
             Loan l = loans.remove(loanId);
             clientLoans.remove(loan);
          }
    
          public Collection<Loan> getAllLoans()
          {
              return loans.values();
          }
    
          public List<Loan> findLoans(Person p)
          {
              List<Loan> loans = clientLoans.get(p);
              if (loans==null)
                  loans = Collections.emptyList();
              return loans;
          }
    
          private Map<Integer,Loan> allLoans = new HashMap<Integer,Loan>();
          private Map<Person, List<Loan>> clientLoans = new HashMap<Person,List<Loan>>();
       }
    

    我希望这有帮助

  3. # 4 楼答案

    您的searchloanarray和loanarray指向同一个数组。这样做

    private Loan[] searchedLoanArray = new Loan[10]
    

    什么都不做,因为你从未使用过那笔新贷款[10]

    这是解决你问题的关键

    searchedLoanArray = this.getAllLoans()
    

    这就把搜索到的loanArray指向了loanArray