Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement binary search in objects

Tags:

Is there any way to implement binary search in a ArrayList with objects? In this example the ArrayList will be sorted with the field 'id'.

class User{  public int id;  public string name; }  ArrayList<User> users = new ArrayList<User>();  sortById(users);  int id = 66 User searchuser = getUserById(users,id); 

How would the "User getUserById( ArrayList users, int userid )" look like if I it should return the user with a specified id using binary search? Is this even possible?

like image 646
Baversjo Avatar asked May 23 '09 17:05

Baversjo


People also ask

In which kind of collection object uses binary search technique when we search for an element in the collection?

binarysearch() works for objects Collections like ArrayList and LinkedList.

Can we do binary search in array?

Binary search works on sorted arrays. Binary search begins by comparing an element in the middle of the array with the target value. If the target value matches the element, its position in the array is returned. If the target value is less than the element, the search continues in the lower half of the array.


2 Answers

The Object Ordering article of The Java Tutorials has an example of writing your own Comparator in order to perform comparisons on custom types.

Then, the ArrayList (or any other List), the key to find, along with Comparator can be passed into the Collections.binarySearch method.

Here's an example:

import java.util.*;  class BinarySearchWithComparator {   public static void main(String[] args)   {     // Please scroll down to see 'User' class implementation.     List<User> l = new ArrayList<User>();     l.add(new User(10, "A"));     l.add(new User(20, "B"));     l.add(new User(30, "C"));      Comparator<User> c = new Comparator<User>() {       public int compare(User u1, User u2) {         return u1.getId().compareTo(u2.getId());       }     };      // Must pass in an object of type 'User' as the key.     // The key is an 'User' with the 'id' which is been searched for.     // The 'name' field is not used in the comparison for the binary search,     // so it can be a dummy value -- here it is omitted with a null.     //     // Also note that the List must be sorted before running binarySearch,     // in this case, the list is already sorted.      int index = Collections.binarySearch(l, new User(20, null), c);     System.out.println(index);    // Output: 1      index = Collections.binarySearch(l, new User(10, null), c);     System.out.println(index);    // Output: 0      index = Collections.binarySearch(l, new User(42, null), c);     System.out.println(index);    // Output: -4                                   // See javadoc for meaning of return value.   } }  class User {   private int id;   private String name;    public User(int id, String name) {     this.id = id;     this.name = name;   }    public Integer getId() {     return Integer.valueOf(id);   } } 
like image 199
coobird Avatar answered Sep 20 '22 12:09

coobird


You could also put the comparator in the User class:

public class User implements Comparable<User>, Comparator<User> {   public User(int id, String name)   {     this.id = id;     this.name = name;   }   @Override   public int compareTo(User u)   {     return id - u.getID();   }   @Override   public int compare(User u1, User u2)   {     return u1.getID() - u2.getID();   }    public int getID() { return id; }   public String getName() { return name; }   private int id;   private String name; } 

Then you would do the following to an ArrayList called users:

ArrayList<User> users = new ArrayList<User>(); users.add(new User(3, "Fred")); users.add(new User(42, "Joe")); users.add(new User(5, "Mary")); users.add(new User(17, "Alice"));  Collections.sort(users); int index = Collections.binarySearch(users, new User(5, null)); if(index >= 0)   System.out.println("The user name of id 5 is: "+users.get(index).getName()); else   System.out.println("ID 5 is not in the list"); 
like image 37
rpw Avatar answered Sep 17 '22 12:09

rpw