JAVA: Best way to determine performance for finding an object stored in hashMap

I have a bunch of objects stored in hashMap<Long,Person>. I need to find a person object with a specific attribute without knowing its identifier.

e.g. class person:

public person{
    long id;
    String firstName;
    String lastName;
    String userName;
    String password;
    String address;
    ..
   (around 7-10 attributes in total)
    }

will say that I want to find an object with username = "mike". Is there a way to find it without actually repeating on the entire hash map as follows:

for (Map.Entry<Long,Person> entry : map.entrySet()) {
        if(entry.getValue().getUserName().equalsIgnoreCase("mike"));

The answers I found here were pretty old.

+4
source share
7 answers

If you want speed and are always looking for one specific attribute, it is best to create another cache hash map associated with this attribute.

, - , .

( ). - , . - :

String ID_PREFIX = "^!^ID^!^";
String USERNAME_PREFIX = "^!^USERNAME^!^";
String FIRSTNAME_PREFIX = "^!^FIRSTNAME^!^";
Map<String,Person> personMap = new HashMap<String,Person>();

//add a person
void addPersonToMap(Person person)
{
    personMap.put(ID_PREFIX+person.id, person);
    personMap.put(USERNAME_PREFIX+person.username, person);
    personMap.put(FIRSTNAME_PREFIX+person.firstname, person);
}

//search person
Person findPersonByID(long id)
{
    return personMap.get(ID_PREFIX+id);
}

Person findPersonByUsername(String username)
{
    return personMap.get(USERNAME_PREFIX+username);
}

//or a more generic version:
//Person foundPerson = findPersonByAttribute(FIRSTNAME_PREFIX, "mike");
Person findPersonByAttribute(String attr, String attr_value)
{
    return personMap.get(attr+attr_value);
}

, . ID , firstname = mike, .

, :

Map<String,List<Person>> personMap = new HashMap<String,List<Person>>();

//add a person
void addPersonToMap(Person person)
{
    insertPersonIntoMap(ID_PREFIX+person.id, person);
    insertPersonIntoMap(USERNAME_PREFIX+person.username, person);
    insertPersonIntoMap(FIRSTNAME_PREFIX+person.firstname, person);
}

//note that List contains no duplicates, so can be called multiple times for the same person.
void insertPersonIntoMap(String key, Person person)
{
    List<Person> personsList = personMap.get(key);
    if(personsList==null)
        personsList = new ArrayList<Person>();
    personsList.add(person);
    personMap.put(key,personsList);
}

//we know id is unique, so we can just get the only person in the list
Person findPersonByID(long id)
{
    List<Person> personList = personMap.get(ID_PREFIX+id);
    if(personList!=null)
        return personList.get(0);

    return null;
}

//get list of persons with firstname
List<Person> findPersonsByFirstName(String firstname)
{
    return personMap.get(FIRSTNAME_PREFIX+firstname);
} 

, , .

+5

, , - HashMap, , , - .

HashMap<String, List<Person>>, . , .

. List<Person> , , username . .

, Person , :

Map<String, List<Person>> peopleByUsername = new HashMap<>();

// ...

Person p = ...;

peopleByUsername.computeIfAbsent(
        p.getUsername(), 
        k -> new ArrayList<>())
    .add(p);

, , i.e joesmith:

List<Person> matching = peopleByUsername.get("joesmith");
+1


, , , , , .


, , (, ), . , , .

, , , , , , .

""
( ), → . ( ), , . , "" , , ( , ).

0

- . "" , .

  • - Long.
  • hashmap Person hashmap (HashMap<String, Person>), .

, .

, - HashMap<Long, Person> idKeyedMap HashMap<String, Person> usernameKeyedMap.

, Map<Object, Person>. , (id, person) , ( , ). , .

0

?

, ​​.

(, , ). select long id , , HashMap<Long, Person>.

, , (.. ). HashMap<String, Person>. Person .

:

Map<String, Person> users = new HashMap<>();
users = retrieveUsersFromDatabase(); // perform db select and build map
String username = "mike";
users.get(username).

, , Person, .

0

Hashmap List, :

list = new ArrayList (map.values ​​());

. , Hashmap Person, .

, . stream api Hashmap .

0

Sorting and searching for a value object can be done by designing and using the appropriate Comparator class.

Comparator class: Designing a comparator for a specific attribute can be performed as follows:

class UserComparator implements Comparator<Person>{

    @Override
    public int compare(Person p1, Person p2) {

        return  p1.userName.compareTo(p2.userName);

    }

}

Usage: The comparator developed above can be used as follows:

    HashMap<Long, Person> personMap = new HashMap<Long, Person>();

                        .
                        .
                        .

    ArrayList<Person> pAL = new ArrayList<Person>(personMap.values()); //create list of values

    Collections.sort(pAL,new UserComparator()); // sort the list using comparator

    Person p = new Person(); // create a dummy object

    p.userName="mike"; // Only set the username

    int i= Collections.binarySearch(pAL,p,new UserComparator()); // search the list using comparator

    if(i>=0){

        Person p1 = pAL.get(Collections.binarySearch(pAL,p,new UserComparator())); //Obtain object if username is present

    }else{

        System.out.println("Insertion point: "+ i); // Returns a negative value if username is not present

    }
0
source

Source: https://habr.com/ru/post/1692378/


All Articles