Implement binary search in objects - java

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?

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);
}
}

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");

Use Collections.binarySearch with a Comparator.

import java.util.Collections;
Collections.binarySearch(users, id);

You should use binarySearch method only on the sorted ArrayList. so First sort the ArraList and use the same comparator reference (which you used to do the sort) to perform the binarySearch operation.

Related

JAVA Store Program isn't outputting the correct numbers

I was creating a Java program for my OOP class. The program is supposed to be the start of a store interface and we are going to build off it during the rest of the semester. Whenever I was to add a new product and try to access how much of it is in stock my program says the "Id DNE -1" which is only supposed to print when an id is called and it doesn't exist. I'm not too sure why it's not recognizing the product I just put in. Below are all my classes that are used. I think the error has to be somewhere in my inventory class but I'm not too sure. Any tips or tricks for OOP would greatly be appreciated as well. Cheers
public class main
{
public static void main(String[] args)
{
StoreManager r3 = new StoreManager();
Inventory r4 = new Inventory();
r4.addNewProduct(1,"apple",1.50,50);
System.out.println(r3.qCheck(1));
}
}
public class StoreManager
{
private Inventory store1 = new Inventory();
private Product store2 = new Product();
static Inventory r4 = new Inventory();
public StoreManager(){}
public int qCheck(int id)
{
if (store1.getStock(id) < 0)
{
System.out.println("Id DNE");
return -1;
} else
{
return store1.getStock(id);
}
}
public double dqcheck(int id, int desiredQuantity) {
if (store1.getStock(id) >= desiredQuantity) {
store1.removeStock(id, desiredQuantity);
double cost = store2.getPrice() * desiredQuantity;
return cost;
}
else {
System.out.println("id DNE");
}
return -1;
}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Inventory
{
//Var Declarations
private int quantity;
// FIXME: 2021-02-07 idk if im usin type right
private Product type;
//Hashmap for the data structure in this class using the Product is gonna be a key
// the value is the Integer for the quantity
private Map<Product,Integer> invt = new HashMap<>();
//blank constructor
public Inventory()
{
}
// FIXME: 2021-02-05 Getter and setter methods not really in use
public int getQuantity(){return quantity;}
public Product getType(){return type;}
/*
Used to initialize a new product and its stock into our Hashmap
the Quantity is the Value of our hashmap while we are using the
Product as a whole to be the key
no return type
*/
public void addNewProduct(int id,String name, double price, int quantity)
{
Product product = new Product(name, id, price);
invt.put(product,quantity);
}
/*
Used to get the get for a given id
compares the Id to one of the ids in the Key values to find the product
returns an int for the amount in stock or a -1 as an error if the id doesn't exist
*/
public int getStock(int id)
{
Set<Product> set = invt.keySet(); // Conversion of keys into sets
Iterator<Product> it = set.iterator(); // the only way i could get the code to interate throughout the keys
while (it.hasNext())//Only way i could go through the code
{
type = it.next();// FIXME: 2021-02-07 Idk if type is being used right here but i needed a buffer variable for it to work
Product a = it.next();
if (a.getId() == id)
{
return invt.get(type);//type is an object of Product here so we can use it as a key
}
}
return -1;//representation of error ID Dne
}
/*
Used to add a given Stock for a given Id
void doesnt return anything
assuming inpputed id exists if Dne doesnt do anythin or return an error
*/
public void addStock(int id, int amountToAdd)
{
//Possibly make this hashmap id check into another private method and call
Set<Product> set = invt.keySet();
Iterator<Product> it = set.iterator();
while (it.hasNext())
{
type = it.next();
if (type.getId() == id)
{
invt.put(type, invt.get(type)+amountToAdd);
return;//exit the function after the addtion is done
}
}
}
/*
Used to remove a given amount of product from stock in reference to a given Id
void doesnt return anythin
assuming id exits otherwise it does nothin
*/
public void removeStock(int id, int amountToRemove)
{
Set<Product> set = invt.keySet();
Iterator<Product> it = set.iterator();
while (it.hasNext())
{
type = it.next();
if (type.getId() == id && invt.get(type) - amountToRemove >= 0)//checks if the id exits and if there whould be enough stock to remove
{
invt.put(type, invt.get(type)-amountToRemove);
return;
}
}
}
/*
Prints all product information in reference to the id
*/
public void getInfo(int id)
{
Set<Product> set = invt.keySet();
Iterator<Product> it = set.iterator();
while (it.hasNext())
{
type = it.next();
if (type.getId() == id)
{
System.out.println("Name: "+type.getName());
System.out.println("Id: "+type.getId());
System.out.println("Price: "+type.getPrice());
System.out.println("Quantity: "+ invt.get(type)); // FIXME: 2021-02-07 Idk if Quanitity and Id are needed here
}
}
}
}
public class Product
{
private String name;
private int Id;
private double price;
public Product(String Name, int Id,double Price)
{
this.name = Name;
this.Id = Id;
this.price = Price;
}
public Product()
{
}
//Getter Methods
public String getName() {return name;}
public int getId() {return Id;}
public double getPrice() {return price;}
}
public class main
{
public static void main(String[] args)
{
StoreManager r3 = new StoreManager();
r3.store1.addNewProduct(1,"apple",1.50,50);
System.out.println(r3.qCheck(1));
}
}
Use the Inventory object that belongs to StoreManager, that's the only one it can access.

Sorting ArrayList of model that is connected with a hashmap

I have an arraylist of model and a hashmap. The model class contains variable such as id(int), name, address, etc. The hashmap, contains id(int) and distance (double). I have tried using Collection to sort a list of model before, but the problem here is, I have to sort the hashmap by it's distance value, and then adjust the arraylist according to how the hashmap sorted. The hashmap's id and the model class' id here act as a "foreign key". Anyone have any idea how to do this?
Here is the hashmap:
HashMap<Integer, String> listDistance = new HashMap<Integer, String>();
listDistance.put(1, 3.22);
listDistance.put(2, 2.57);
listDistance.put(3, 6.32);
listDistance.put(4, 8.82);
listDistance.put(5, 1.32);
Here is the arraylist:
ArrayList<Listing> listings = new ArrayList<Listing>();
listing.add(1, "asd", 123);
listing.add(2, "ghf", 3434);
listing.add(3, "ert", 876);
listing.add(4, "tyi", 1267);
listing.add(5, "ohg", 1345);
Here is the model class:
public class Listing {
int id, count;
String name;
public Listing(int id, String name, int count) {
this.id = id;
this.count = count;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The result of what I want should sort the listings to become like this:
listing.add(5, "ohg", 1345);
listing.add(2, "ghf", 3434);
listing.add(1, "asd", 123);
listing.add(3, "ert", 876);
listing.add(4, "tyi", 1267);
I actually haven't tried anything to make this works except thinking the logical flow because I am quite out of idea as to how to do this.
You can sort the list like this:
Collections.sort(listing, (a,b) -> Double.compare(listDistance.get(a.getId()),
listDistance.get(b.getId())));
See running code at IDEONE.

I want to get individual element of an arrayList in Java

I am newbie in java and I have a method that accepts 3 parameters, query the db and returns result in an arraylist form (like this [1, Java, 3, Bangalore, 10] ). How can i extract individual element so that I can assign each to a var like int id=1;String name=Java.
Below is the method that
ArrayList searchResult =jSearch.doJobSearch(techName, exp, city);
Iterator searchResultIterator = searchResult.iterator();
PrintWriter out = response.getWriter();
String arrayList[] = new String[searchResult.size()];
if(searchResultIterator.hasNext()){
for(int i =0; i<searchResult.size(); i++){
//searchResult.get(i)
out.println(searchResult.get(i));
}
}else{
out.println("No Job found in selected city");
}
ArrayList works in the sense of [index, element].
By using the get method, you're using index as the parameter and it returns the element at that position. So if you're accessing the element by it's index you already have both the id and element, but a different collection interface might suit you better like a map.
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Create POJO (Plain Old Java Object). I am providing example how to array list is used when store Real time Object.
package com.appkart.examples;
public class Employee {
private int id;
private String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And Add Employee into Array list and get values
package com.appkart.examples;
import java.util.ArrayList;
public class Program {
public static void main(String[] args) {
ArrayList<Employee> employees = new ArrayList<Employee>();
Employee arun = new Employee(10, "Arun");
Employee ankit = new Employee(20, "Ankit");
Employee jon = new Employee(30, "Jon");
Employee anil = new Employee(40, "Anil");
employees.add(arun);
employees.add(ankit);
employees.add(jon);
employees.add(anil);
for (Employee employee : employees) {
int id = employee.getId();
String name = employee.getName();
System.out.println("id : "+id +" name : "+name);
}
}
}

how to have a unique student Id

The problem is that I cant create a unique Student number, Sometimes I get the same student Id when i store a student, is there anyway of generating unique studentID numbers, I need to amend the store method so its creating a unique
public class Collection
{
private ArrayList<Student> studentList;
public Collection()
{
studentList = new ArrayList<Student>();
}
public void storeStudent(Student student)
{
student.setId(createId("AB",9));
studentList.add(student);
}
public String createId(String pre, int number)
{
Random random = new Random();
int index = random.nextInt(number);
return pre + index + " ";
}
}
public class Student
{
private String studentId;
private String name;
public Student( String name)
{
studentId = "UnKnow";
this.name = name;
}
public void setId(String id)
{
studentId = id;
}
}
You could use a UUID:
public String createId() //don't need the arguments any more
{
UUID uuid = UUID.randomUUID();
return uuid.toString();
}
Extremely unlikely to ever have a clash.
make the studentId variable static and create static method to generate studentId.
private static studentId = 0;
...
public static int generateStudentId()
{
return studentId++;
}
you might also want to store this value to db or file or whatsoever, in case you stop the app and relaunch.
private static final AtomicInteger idIncrement = new AtomicInteger();
public static String createId(String pre /*, int number -- no longer needed*/)
{
int index = idIncrement.incrementAndGet();
return pre + index + " ";
}
This would give you thread-safe unique ordered student ids.
Try to use Set in collections. It will not allow duplicates. Also you can easily convert Set into List as follows.
List<T> list = new ArrayList<T>(set);
Brief tutorial on set.
Hope this will helpful to you.
Thanks you.
try
class Collection {
static long id = System.currentTimeMillis();
public void storeStudent(Student student) {
student.setId(++id + "");
studentList.add(student);
}
It guarantees unique IDs even after you restart the app. Note that it is not thread safe, if you need it to be thread-safe use AtomicLong id = new AtomicLong(System.currentTimeMillis).

Sort a list of object w.r.t to a particular member/state in descending order

I have a list of java object that have 4 members.
int id;
String name;
String age;
int order;
I am using his code to sort object fields in ascending order according to if condition.
Collections.sort(list, new Comparator<com.MyObject>() {
public int compare(com.MyObject object1, com.MyObject object2) {
if(myString.equalsIgnoreCase("name")){
return object1.getName().compareTo(object2.getName());
}else if(myString.equalsIgnoreCase("age")){
return object1.getAge().compareTo(object2.getAge());
}else{
return object1.getOrder() - object2.getOrder();
}
}
});
I want to add another condition if(myString.equalsIgnoreCase("nameReverse")) If this will be the case the list should be sorted in descending order.
The Collections class has a reverseOrder method which returns a reverse Comparator for a given comparator. IMO, it would be more cleaner to not modify the Comparator if all you want to do is get a reverse Comparator.
A bit of sample code:
public class Person {
public static void testComparator() {
Person p1 = new Person("c");
Person p2 = new Person("a");
Person p3 = new Person("b");
List<Person> persons = Arrays.asList(p1, p2, p3);
Collections.sort(persons, PersonComparator.INSTANCE);
System.out.println("After normal sorting: " + persons);
Collections.sort(persons, Collections.reverseOrder(PersonComparator.INSTANCE));
System.out.println("After reverse sorting: " + persons);
}
public Person(String name) { this.name = name; }
public String name;
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Person [name=").append(name).append("]");
return builder.toString();
}
}
class PersonComparator implements Comparator<Person> {
public static final PersonComparator INSTANCE = new PersonComparator();
#Override
public int compare(Person o1, Person o2) {
return o1.name.compareTo(o2.name);
}
}

Categories

Resources