Okay so let's say I have a really simple class, e.g.
public class Baby {
private String Name = "alf";
public String getName() {
return Name;
}
}
Now what I'd like to know. Given a list of Baby's, is there any niftier/cooler/shorter way in Java to create an array/arraylist of the Baby's names' rather than simple looping through all the babies and adding their names to the new list? The equivalent of this:
ArrayList<Baby> babies = new ArrayList<Baby>();
/* some code adding a bunch of babies to the arraylist */
ArrayList<String> names = new ArrayList<String>();
for (Baby b : babies) {
names.add(b.getName());
}
...but cooler. Know what I mean?
You could use Guava's Lists.transform
:
Function<Baby, String> getBabyNameFunction = new Function<Baby, String>() {
@Override
public String apply(Baby baby) {
return baby.getName();
}
};
List<String> babyNames = Lists.transform(babies, getBabyNameFunction);
The key difference here being that babyNames
is a view of the original list on which the transformations are lazily performed. From the documentation:
The function is applied lazily, invoked when needed. This is necessary for the returned list to be a view, but it means that the function will be applied many times for bulk operations like
List.contains(java.lang.Object)
andList.hashCode()
. For this to perform well, function should be fast. To avoid lazy evaluation when the returned list doesn't need to be a view, copy the returned list into a new list of your choosing.
Obviously the syntax for implementing the Function
is rather verbose - that's Java for you until lambdas. I typically keep commonly used functions as constants to avoid clutter and re-instantiation at the call site:
public class Baby {
...
public static class Functions {
private static final Function<Baby, String> GET_NAME =
new Function<Baby, String>() {
@Override
public String apply(Baby baby) {
return baby.getName();
}
};
private Functions() { }
public static Function<Baby, String> getName() {
return GET_NAME;
}
}
}
Yes, it's even more code but it's hidden away and more maintainable. Then at the call site:
List<String> babyNames = Lists.transform(babies, Baby.Functions.getName());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With