1

I have an object Customer with an attribute id that is an int. I'm trying to use Collections builtin sort and search features with a lambda comparator. My question is, why does this seem to work:

Collections.sort(customers, (a, b) -> a.getID() - b.getID());

But this does not:

foundIndex = Collections.binarySearch(customers, custID, 
                    (a, b) -> a.getID() - b.getID());

When I say 'seem to work' I mean it runs with no errors. Specifically with the second line, Eclipse has a problem with .getID() . It gave me a casting suggestion, which I tried:

foundIndex = Collections.binarySearch(customers, custID, 
                    (a, b) -> ((Customer) a).getID() - ((Customer) b).getID());

But that ran into a runtime error that said "Integer can not be cast to class Customer" When I try to cast inside the (a, b) Eclipse doesn't like that either. Will any lambda do what I want in the binarySearch part?

2
  • 7
    binarySearch expects a value of the same type as your list elements, so you need to pass it a customer, not a customer's ID. Admittedly, I would be inclined to agree that the API is flawed (accepting a value of the key type makes more sense here), but that's Java for you. Commented Jul 10, 2021 at 22:36
  • 1
    omg, Thank you so much! That's all it was. Works great now. I found it so weird there is so much help regarding lambdas and sort, but nothing really on search. Again, thank you! Commented Jul 10, 2021 at 22:53

2 Answers 2

4

Have you tried providing an instance of the Customer class instead of an ID?

foundIndex = Collections.binarySearch(customers, customer, 
                    (a, b) -> a.getID() - b.getID());
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, as per Silvio Mayolo's comment and my answer below.
0

As commenter Silvio Mayolo stated, the problem isn't really the lambda it is what is expected by the key argument in Collections.binarySearch().

This works exactly as I wanted:

//assumes presorted customers ArrayList, thank you commenter gOOse
public Customer findCustomer(int custID) {
        int foundIndex;
        Customer key = new Customer(custID, null);
        
        readLock.lock();
        try {
            foundIndex = Collections.binarySearch(customers, key, 
                (a, b) -> a.getID() - b.getID());       
            return (foundIndex > -1) ? customers.get(foundIndex) : null;
        }
        finally { readLock.unlock(); }
    }

2 Comments

Don't forget that collections need to be sorted before binary searches work properly
Yes, this answer assumes the list is already sorted. This code is directly from what I am using, and the list is already sorted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.