Extracting objects from List<X> based on some other list property collection
I've a class -
public class Data implements Identifiable{
private Integer id;
public Integer getId(){
return id;
}
}
now I've two collections-
List<Data> data1 = // few hundred Objects
Set<Integer> dataIds = // few object ids
I would 开发者_如何学编程like to extract the List<Data>
from data1
which has ids in dataIds
How should be my approach? I'va guava in my classpath so can go with guava's Functional approach if comparable in performance/efficiency .
Unless all you want to do is iterate through the result once or you need a reusable live filtered view, you probably want a non-view list containing the matches. Creating a List
or Set
to store the result and then iterating through the data list and adding matches is a perfectly good approach and easy to understand!
List<Data> result = Lists.newArrayList();
for (Data data : data1) {
if (dataIds.contains(data.getId()))
result.add(data);
}
I see your Data
class implements an Identifiable
interface. Given that, you could create a Function<Identifiable, Integer>
that gets the ID... Identifiables.getIdFunction()
or something. This is nice because it'd likely be useful in various other places (I talk about that approach in a blog post here). With that in place, doing this with Guava would be fairly simple as well:
Predicate<Identifiable> predicate = Predicates.compose(
Predicates.in(dataIds), Identifiables.getIdFunction());
List<Data> filtered = Lists.newArrayList(Iterables.filter(data1, predicate));
This is basically functionally equivalent to the first example, but seems like it'd be harder to understand. Since there isn't any clear benefit to doing this (unlike in a situation where you want to just use the live view), my recommendation would be to just go with the first.
How about
Collections2.filter(
data1,
new Predicate<Data>() {
public boolean apply(Data d) {
return dataIds.contains(d.getId());
}
}
)
p.s. remember not to overcomplicate things, unless truly necessary.
With LambdaJ you could write:
List<Data> result = extract(data1, on(Data.class).getId());
精彩评论