1

I need to add Person p to the contacts ArrayList unless it contains the same surname and first name.

In that case I need to return an error message "could not add person". Here is my current code:

public class AddressBook {
 private ArrayList<Person> contacts;
   public AddressBook(){
    this.contacts = new ArrayList<Person>();
 }    

  public void addPerson(Person p) {
   for (int i = 0; i < contacts.size(); i++) {
    if(contacts.get(i).getfirstName().equals(p.firstName)){
        System.out.printf("could not add person");
    }
   }
   this.contacts.add(p);
  }            

I am having trouble figuring out how I should compare the strings about to be added via the addPerson() method with the existing strings contained within the Person object already contained within the list.

GhostCat
  • 127,190
  • 21
  • 146
  • 218
hK-
  • 27
  • 1
  • 4
  • From the snippet it seems like you have the right idea. What exactly is the problem? – Mureinik Apr 06 '17 at 07:47
  • 1
    According to your specific situation, it _might_ be good to appropriately implement the `equals` method in `Person` and use it for comparison (if first and last name are the only fields in it). – rrobby86 Apr 06 '17 at 07:50
  • Make Person object Comparable then you can compare any field of person to decide they are same person or not – user1756634 Apr 06 '17 at 08:26

5 Answers5

1

I think you shouldn't use a List to do this. If you want a collection which reject duplicates, you should use a Set.

So in my opinion you should change your code with something like this :

public class AddressBook {

  // You have to use a LinkedHashSet instead of a HashSet if you want to keep order
  private Set<Person> contacts = new HashSet<>();

  // v1 : add p only if not present in contacts and don't log anything
  public void addPerson(Person p) {
    contacts.add(p);
  }

  // v2 : log if duplicate
  public void addPerson(Person p) {
    if(contacts.contains(p))
      System.out.println("Duplicate here");
    else
      contacts.add(p);
  }

  // If you really need an List (maybe to be compatible with an API ?)
  public List<Person> asList() {
    return new ArrayList<>(contacts);
  }
} 

To use this code, you have to implement the hashCode and the equals method in your Person class. But I think it's a better way to do this.

Dorian
  • 706
  • 3
  • 13
  • 26
  • Yes, a `Set`is to be used here with proper implementation of `equals` and `hashcode`in `Person` or a custom `Comparator`could be provided to the constructor of the Set. – DerMike Apr 06 '17 at 08:26
  • @DerMike OP asked for a solution with arraylist and not with set. he might be able/allowed to use set but the question does not state so and therefore a set might not be the solution he needs – XtremeBaumer Apr 06 '17 at 08:28
  • @XtremeBaumer It might not be the solution he needs it's true, but if he has the choice, he should use a `Set` here, not a `List`. So I think it's important to show a better way to do this. – Dorian Apr 06 '17 at 08:31
  • @Dorian thats true, but in case he is a beginner arraylist is an easier use – XtremeBaumer Apr 06 '17 at 08:34
  • Yeah it's for an assignment and I need to use arraylists. – hK- Apr 06 '17 at 08:38
  • 1
    Then of course it's not your fault but still... And IMHO beginners should learn the appropriate data structures the framework offers and experts should tell them instead of blindly answer questions true to the letter. – DerMike Apr 07 '17 at 11:05
1

The real trick here: step back and improve your model.

What you actually are saying is: when two Person objects have the same first/last name; then you want to consider them to be equal.

In that sense: just go forward and override equals (and hashCode) within that Person class; see here for how to do that in great detail.

Because then you can step back; and use a lot of the built-in features of Java collections; like the List.contains() method! You neither have nor should implement such kind of checking yourself. Instead, you look how the "framework" works; and make your code work within the framework.

Beyond that: I understand that this is probably for "learning" purposes; but: in the real world; two people are not necessarily the same person just because they share their names. To the contrary: a real-world address book should allow adding multiple John Doe guys with different addresses (maybe giving a warning when doing it; but still: allowing it).

Community
  • 1
  • 1
GhostCat
  • 127,190
  • 21
  • 146
  • 218
0
public void addPerson(Person p) {
    boolean isInList=false;
    for(Person per : contacts){
        if(per.getfirstName().equals(p.firstName)&&per.getsurName().equals(p.surName)){
            System.out.printf("could not add person");
            isInList=true;
        }
    }
    if(!isInList){
        this.contacts.add(p):
    }
}

this code checks if a person with the same surname and first name already exists in list. if yes it wont be added, otherwise it gets added. the only flaw that might be is that you can have the same "person" if you have 1 person with capital letter in list and want to add the same surname and first name only with lower case letters

XtremeBaumer
  • 5,158
  • 1
  • 15
  • 44
  • 1
    No, `java.util.Set` would be the proper way to solve the issue at hand. – DerMike Apr 06 '17 at 08:24
  • I'm getting the error "firstName has private access in Person" Any ideas? – hK- Apr 06 '17 at 08:56
  • @hK-, when `Person` has a `private String firstName` then `.equals(p.firstName)` will get you an error like that. Either use the getter (`p.getFirstName()`) or make it `public` (which might be considered a hack ;-)). – DerMike Apr 07 '17 at 10:56
0

Whenever you called addPerson method the contacts.add(p) is also called. Add return statement inside your if condition then it wont call if the list has same first name and surname object.

public void addPerson(Person p) {        
      for (int i = 0; i < contacts.size(); i++) {
        Person p2=contacts.get(i);
        if(p2.getfirstName().equals(p.firstName) && p2.getSurName().equals(p.surName)){
            System.out.printf("could not add person");
            return;
        }
    }
    this.contacts.add(p);
}
Suresh A
  • 1,128
  • 1
  • 10
  • 21
0

In the Person object implement hashCode and equals method as below

@Override
public int hashCode() {
    return Objects.hash(firstName.toLowerCase(), lastName.toLowerCase());
}

@Override
public boolean equals(Object obj) {
    if(null != obj && obj instanceof Person) {
        return this.firstName.equalsIgnoreCase(((Person)obj).getFirstName()) && this.lastName.equalsIgnoreCase(((Person)obj).getLastName());
    }
    return false;
}

This will ensure that the Person object will be added only if the firstName and lastName are unique.

Ram
  • 56
  • 5
  • You shoul'd check for `!= null` and `instanceof Person` in the `equals` method, and you shouldn't use a `if (myCondition) return true; else return false;`, just `return myCondition` – Dorian Apr 06 '17 at 12:25