mgamer mgamer - 1 month ago 14
Java Question

Java - map a list of objects to a list with values of their property attributes

I have the ViewValue class defined as follows:

class ViewValue {

private Long id;
private Integer value;
private String description;
private View view;
private Double defaultFeeRate;

// getters and setters for all properties
}


Somewhere in my code i need to convert a list of ViewValue instances to a list containing values of id fields from corresponding ViewValue.

I do it using foreach loop:

List<Long> toIdsList(List<ViewValue> viewValues) {

List<Long> ids = new ArrayList<Long>();

for (ViewValue viewValue : viewValues) {
ids.add(viewValue.getId());
}

return ids;


}

Is there a better approach to this problem?

Answer

EDIT: This answer is based on the idea that you'll need to do similar things for different entities and different properties elsewhere in your code. If you only need to convert the list of ViewValues to a list of Longs by ID, then stick with your original code. If you want a more reusable solution, however, read on...

I would declare an interface for the projection, e.g.

public interface Function<Arg,Result>
{
    public Result apply(Arg arg);
}

Then you can write a single generic conversion method:

public <Source, Result> List<Result> convertAll(List<Source> source,
    Function<Source, Result> projection)
{
    ArrayList<Result> results = new ArrayList<Result>();
    for (Source element : source)
    {
         results.add(projection.apply(element));
    }
    return results;
}

Then you can define simple projections like this:

private static final Function<ViewValue, Long> ID_PROJECTION =
    new Function<ViewValue, Long>()
    {
        public Long apply(ViewValue x)
        {
            return x.getId();
        }
    };

And apply it just like this:

List<Long> ids = convertAll(values, ID_PROJECTION);

(Obviously using K&R bracing and longer lines makes the projection declaration a bit shorter :)

Frankly all of this would be a lot nicer with lambda expressions, but never mind...