Reputation: 3331
Got some interesting logic that I am trying to encode in the most efficient and readable way possible. I will lay out the scneario below (with a simulated/dummy context)
I have a data store of banks and their teller reviews (1-5 int field). A teller can optionally have a Customer Choice Winner (CCW) field. My requirements are as below to choose at most 5 tellers for a given bank to display to the user:
I have to do the above for 5 banks. The logic I was getting was have a for loop to go over the 5 banks and within each loop, go over all tellers for each bank 5 times (to pick 5 tellers). This seems to me to be really inefficient and unclear. Here is what I mean:
foreach (Bank b : banks) {
List<Tellers> tellers = b.getTellers();
foreach (Teller t : tellers) {
List<Reviews> reviews = t.getReviews();
...// get 4 reviews following the above logic.
}
}
Can anyone help me with a clearer and more efficient way to write this?
Thanks!
Upvotes: 2
Views: 83
Reputation: 17548
The best solution for this is to sort the List<Teller>
You will have to define a compare function for the Teller object by implementing the Comparable interface.
This will let you run your algorithm in constant time (O(25) because of 5 tellers for 5 banks, which is really O(1))
At the cost of sorting it the first time, which will be O(nlogn)
Example code for your Teller class:
public class Teller implements Comparable
{
private boolean ccw = false;
private int rating;
public boolean hasCCW() { return ccw; }
public int getRating() { return rating; }
//... your code
@Override
public int compareTo(Object o)
{
Teller that = (Teller)o;
//if this has ccw and that doesn't, this < that
if(this.hasCCW() && !that.hasCCW())
{
return -1;
}
//else if this does not have ccw, and that does, this > that
else if(!this.hasCCW() && that.hasCCW())
{
return 1;
}
//else they both have ccw, so compare ratings
else
{
return Integer.compare(this.getRating(), that.getRating());
}
}
}
Then, your algorithm will just need to grab the first 5 tellers for each bank.
example:
//Sort the tellers:
//ideally, call this only once, and insert future Tellers in order (to maintain ordering)
for(Bank bank : banks)
{
for(List<Teller> tellers : bank.getTellers())
{
Collections.sort(tellers);
}
}
//then, to get your top tellers:
for(Bank bank : banks)
{
Teller bestTeller = bank.getTeller(0);
Teller secondBestTeller = bank.getTeller(1);
//...
}
Upvotes: 1