Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a list of values from getters of a List of objects

Tags:

java

list

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?

like image 567
user891876 Avatar asked Oct 06 '22 00:10

user891876


1 Answers

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) and List.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());
like image 79
Paul Bellora Avatar answered Oct 10 '22 20:10

Paul Bellora