8

What i want to do is store some instances of my class on a list and get a specific instance from that list.

This is an example of a custom class

public class Person
{
    private String name;
    //Several unrelevant fields here

    public Person(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }

    //Several unrelevant methods here
}

And this is the code i'm currently using to get one of the instances on the list, that is on the main class.

public class Main
{
    private List<Person> people = new ArrayList<Person>();
    //More unrelevant fields here

    public Person getPerson(String name)
    {
        for (Person p : people)
            if (p.getName().equalsIgnoreCase(name))
                return p;
        return null;
    }
    //More unrelevant methods here
}

My question is if there's any other way to write this to increase the performance.

user2605421
  • 187
  • 1
  • 3
  • 9
  • I'd just like to note that your data encapsulation appears to be very pointless as you are not checking for a valid replacement for `name` in your mutator method. You should just make `name` public for faster access. – Josh M Sep 26 '13 at 19:49
  • 2
    "for faster access" is a horrific reason to make a class variable public more than 99% of the time. – Eric Stein Sep 26 '13 at 19:52
  • @EricStein That wasn't my only reasoning (read proceeding sentence). If you don't mind, perhaps you should explain the reason why `name` is encapsulated because frankly I don't see any point to it. – Josh M Sep 26 '13 at 19:56
  • @JoshM http://stackoverflow.com/questions/1568091/why-use-getters-and-setters – Mike Clark Sep 26 '13 at 20:00
  • @MikeClark Majority of those reasons don't even apply given these circumstances... – Josh M Sep 26 '13 at 20:30
  • @JoshM This argument about "never use setters/getters" vs. "only use them when they're useful" vs. "just always use them" will never be settled. It's just too much of a context-dependent issue to be dogmatic about it. – Mike Clark Sep 26 '13 at 20:41

3 Answers3

15

Use a Map whose keys are the names and whose values are the people.

Eric Stein
  • 13,209
  • 3
  • 37
  • 52
3

HashMap is case sensitive. If you wanted case-insensitive lookups, you could use a TreeMap. My example demonstrates that people with the same name (case insensitively) overwrite each other.

import java.util.Map;
import java.util.TreeMap;

public class SoMain {
    Map<String, Person> nameToPersonMap = 
            new TreeMap<String, Person>(String.CASE_INSENSITIVE_ORDER);

    public static void main(String[] args) {
        new SoMain().run(args);
    }

    private void run(String[] args) {
        addPerson(new Person("Jim McDonald", 1));
        addPerson(new Person("Jim Mcdonald", 2));
        addPerson(new Person("John Smith", 3));

        System.out.println("Number of people: " 
                    + nameToPersonMap.entrySet().size());
        System.out.println("Jim McDonald id: " 
                    + getPerson("Jim McDonald").getPersonId());
        System.out.println("John Smith id: " 
                    + getPerson("john smith").getPersonId());
    }

    private void addPerson(Person p) {
        nameToPersonMap.put(p.getName(), p);
    }

    private Person getPerson(String name) {
        return nameToPersonMap.get(name);
    }

    public static class Person {
        private String name;
        private int personId;

        public Person(String name, int personId) {
            this.name = name;
            this.personId = personId;
        }

        public int getPersonId() {
            return personId;
        }

        public String getName() {
            return name;
        }
    }
}
Mike Clark
  • 10,027
  • 3
  • 40
  • 54
1

As Eric mentions, you should use a HashMap, the reasoning for this is because you can look up and add data to one very quickly (on average).

Here is a code example of how to use HashMap using Person.name as the key, this assumes that there is never a person with the same name.

public class Main
{
    private HashMap<String, Person> people = new HashMap<String, Person>();

    public void addPerson(Person person)
    {
        people.put(person.getName(), person);
    }

    public Person getPerson(String name)
    {
        // get returns null when not found
        return people.get(name);
    }
}
Daniel Imms
  • 47,944
  • 19
  • 150
  • 166
  • This code does not even compile: First of all, you are not allowed to have primitive types when specifying generic type arguments. Secondly, `person.getName()` returns a `String`, not an `int`. If was an `int`, you would have to put `Integer` instead. – Josh M Sep 26 '13 at 19:51