eclipse / eclipse-collections

Eclipse Collections is a collections framework for Java with optimized data structures and a rich, functional and fluent API.

Home Page:http://www.eclipse.org/collections

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add selectBy/rejectBy to RichIterable

donraab opened this issue · comments

Filtering a collection based on some attribute of an object is a fairly common activity. There are things like Predicates.attributeEqual(Function, Object) in the Eclipse Collections library that help construct a Predicate out of a Function and an equality test. There is also the more general Predicates.attributePredicate(Function, Predicate). These factories were more useful in the time before we had lambdas. They are verbose in comparison. The methods selectBy/rejectBy would be more concise with method references.

Here's an example of using selectBy from the CompanyKata:

// select
MutableList<Customer> customersFromLondon = 
        this.company.getCustomers().select(customer -> "London".equalsIgnoreCase(customer.getCity()));

// select using Predicates.attributePredicate
MutableList<Customer> customersFromLondon =
        this.company.getCustomers().select(Predicates.attributePredicate(Customer::getCity, "London"::equalsIgnoreCase));

// selectWith
MutableList<Customer> customersFromLondon =
        this.company.getCustomers().selectWith(Customer::livesIn, "London");

// Using selectWith requires adding a livesIn method to Customer class.
public boolean livesIn(String aCity)
{
    return this.city.equalsIgnoreCase(aCity);
}

// selectBy
MutableList<Customer> customersFromLondon =
        this.company.getCustomers().selectBy(Customer::getCity, "London"::equalsIgnoreCase);

The methods selectBy and rejectBy would complement the other By methods like groupBy, countBy, containsBy.

I have submitted this as a committer discussion because while I believe this functionality is potentially useful, it could also be costly to implement as it would have to be specified across all of our interfaces to return the same types as select and reject. So I'd like to hear opinions if it is worth expanding the API with these two methods.

@prathasirisha @motlin @nikhilnanivadekar

@motlin @nikhilnanivadekar @prathasirisha Thoughts on adding selectBy/rejectBy to RichIterable? My gut feeling is we're already at our budget for adding new methods to RichIterable but wanted opinions from some other folks who have taught the EC Kata as this is where my example is from.

I don't feel super strongly but I would lean toward not adding these methods.

The cost is that they have covariant return types which makes them a lot of work to add. They'd appear in auto-complete, and there are already a lot of choices there.

The benefit in the Kata example is that we could shorten this.company.getCustomers().select(customer -> "London".equalsIgnoreCase(customer.getCity())) to this.company.getCustomers().selectBy(Customer::getCity, "London"::equalsIgnoreCase). That feels like a pretty limited improvement, and I'd still prefer this.company.getCustomers().selectWith(Customer::livesIn, "London") when the selectWith form is possible.