Search code examples
javagenericstransformer-modelapache-commons-collection

Java: Commons-Collections generics: How to get custom transformer to work


Hi i am using commons collections generics 4.01.

I have a dto object.

Class PricingDto {
   private Double tax;
   private Double price;
   private Double tip;

   // getters and setters
}

i have a list of List<PricingDto> pricingDtos = this.pricingService.getAllPricings();

than i have a private static class.

import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.list.TransformedList;

class TotalServiceImpl implements TotalService {
    public static final PricingDtoTransformer PRICING_DTO_TRANSFORMER =
        new PricingDtoTransformer();
    private static class PricingDtoTransformer
        implements Transformer<PricingDto, Double> {
        public PricingDtoTransformer() {}

        @Override
        public Double transform(final PricingDto pricingDto) {
            return pricingDto.getTax()
                     + pricingDto.getPrice()
                     + pricingDto.getTips();
        }
    }

    @Override
    public List<Double> getListDouble(final List<PricingDto> pricingDtos) {
        final List<Double> totalList = 
            TransformedList.decorate(pricingDtos, PRICING_DTO_TRANSFORMER);
            for (Double d : totalList) {
                // print them. 
            }
        }
    }
}

My problem is i get class cast exception, because each item in totalList is a PricingDto and not Double.

2.) What did i do wrong. Whats the correct way to implement custom transformer for generics commons-collections.


Solution

  • Transforming the collections in place seems like an awful hack to me. I'd suggest using Google Guava instead. It's Lists.transform(List,Function) returns a view that is backed by the original List and a mapping function, so you're not actually changing anything.

    Here's what your code would look like:

    class TotalServiceImpl implements TotalService{
    
        private static final Function<PricingDto, Double> PRICING_DTO_TRANSFORMER =
            new PricingDtoTransformer();
    
        private static class PricingDtoTransformer implements
            Function<PricingDto, Double>{
    
            public PricingDtoTransformer(){
            }
    
            @Override
            public Double apply(final PricingDto pricingDto){
                return pricingDto.getTax() + pricingDto.getPrice()
                    + pricingDto.getTips();
            }
        }
    
        public List<Double> getListDouble(final List<PricingDto> pricingDtos){
            final List<Double> totalList =
                Lists.transform(pricingDtos, PRICING_DTO_TRANSFORMER);
            for(final Double d : totalList){
                // print them.
            }
            return totalList;
        }
    
    }
    

    Commons-Collections might also have a similar mechanism, but I couldn't find it at first glance.