简体   繁体   中英

Returning searched results in an array in Java without ArrayList

I started down this path of implementing a simple search in an array for a hw assignment without knowing we could use ArrayList. I realized it had some bugs in it and figured I'd still try to know what my bug is before using ArrayList. I basically have a class where I can add, remove, or search from an array.

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
}

When testing this, I thought it worked, but I think I am overwriting my member variable after I do a search. I initially thought that I could create a new Loan[] in the method and return that, but that didn't seem to work. Then I thought I could have two arrays. One that would not change, and the other just for the searched values. But I think I am not understanding something, like shallow vs deep copying???....

The return value from getAllLoans is overwriting the searchedLoanArray reference, which means that both loanArray and searchedLoanArray are pointing at the same underlying array. Try making searchedLoanArray a local variable, and then use Arrays.copyOf. If you're trying not to use standard functions for your homework, manually create a new Loan array of the same size as loanArray, and then loop and copy the values over.

your searchloanarray and loanarray point to the same array. doing this

private Loan[] searchedLoanArray = new Loan[10]

does nothing as you never use that new Loan[10]

this is the key to your problem

searchedLoanArray = this.getAllLoans()

that just points searchedLoanArray at loanArray

You could rewrite it like this:

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

}

But as it stands, the code still has some problems:

  1. The maximum number of loans is fixed to the size of the array. You will avoid this problem when you switch to List<Loan> .
  2. Using the id as an index means that your ids must be carefully generated. If IDs come from a database, you may find that the list tries to allocate a huge amount of memory to size itself to match the Id. You would be better using a Map, then the size of the map is based on the number of loans, rather than their IDs.
  3. As the number of people and loans increase, the search time will also increase. You can reduce search time to a constant (irrespective of how many People) by using a Map>, which allows quick lookup of the loans associated just with that person.

Here's a version with these changes:

   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>>();
   }

I hope this helps!

What I would do is loop through the values and reassign each value to the new variable. Alternatively, you could use "deep copy" technique as described here in Javaworld: http://www.javaworld.com/javaworld/javatips/jw-javatip76.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM