Finding a value in a list
I have a list declared as
private List<Employees> employees;
and i get values ββfrom database using DAO like
employees= new ArrayList<Employees>();
employees.addAll(myDAO.getEmployees());
I would like to find the value in employees List
, what is the best approach to find the value in employees List
?
I tried
Collections.sort(employees);
int index = Collections.binarySearch(employees, "abc");
However I am getting a cast Exception
Any help is appreciated.
thank
source to share
Collections.sort(employees); // BigO - nlog(n)
int index = Collections.binarySearch(employees, new Employee("abc",...)); // BigO - log(n)
if you sort every time your list is and search for it, the complexity of the code will be nlog(n) + log(n)
where nlog(n)
for sorting a list and log(n)
for a binary search.
It's best if you search your list linearly. the search for a liner will take BigO - n
, which will work better than the previous one.
You are getting a method cast Exception
in Collections#sort
because your list contains null value
which cannot use Employee and raiseClassCastException
source to share
If you cannot use
myDAO.getEmployees(parameter);
and in your DAO put a where clause then you can search and find the object
Employee emp = null;
for(Employee e : employees) {
if(e.getName().equals("X"))
emp = e;
}
if(emp != null) {
//handle the found employee
}
else {
//employee not in list
}
Of course, you can also override its equals method, initialize an object with that column and use (I wouldn't recommend it)
myDAO.getEmployees().get(object);
source to share
Go through the list and perform a search action:
String searchString = "abc";
for(Employee employee: employees) {
if(employee.getName().equals(searchString)) {
// Found something!
}
}
If you want to search for all fields Employee
, you may need to create a method in Employee
that checks all fields of an instance:
boolean findString(String searchString) {
if(getName().equals(searchString)) return true;
if(getCity().equals(searchString)) return true;
// etc..
return false;
}
and use this method in for
-loop.
source to share
If your list is very large, I suggest doing a DAO search - the dbs can be tuned for better performance for such a search (for example select * from employees where name = 'abc'
) and then use the DAO method to return only the items that match.
Another nice alternative is apache-commons Predicate
eg,
matches = CollectionUtils.filter(employees, new Predicate<Employee>()
{
@Override
public boolean evaluate(Employee object)
return "abc".equals(object.getName());
}
});
Obviously, we parameterize "abc". Make Predicate a named class if you want to reuse it.
Predicate implementations are especially useful if you have many different ways to filter a filter; plus it leaves equal free for correct equality checks.
source to share
You are on the right track. Just override the equals method in Employees (shouldn't it be Employee? Does it describe a collection of employees, or just one?)
Then your code should work. You can also sort your employees as above and provide a comparator:
Collections.sort(fields, new Comparator<Employee>() {
@Override
public int compare(Employee o1,Employee o2) {
// TODO Rerturn 0 if equal or either 1 or -1 depending which of o1 or o2 is the bigger
}
})
In the last approach, you DO NOT need to override the equals method.
source to share