Refactoring for DRY

Peter Levart peter.levart at gmail.com
Tue Apr 9 05:08:00 PDT 2013


With some utilities like:

https://github.com/plevart/streamx/blob/master/main/src/si/pele/streamx/Streamable.java

The re-use can be accomplished in another fashion:


         Streamable<Person> peoples = people::parallelStream;

         Streamable<Person> filteredPeoples = peoples
             .filter(p -> p.getAge() >= 12)
             .filter(p -> p.getAge() < 65);

         filteredPeoples.stream()
             .forEach(p -> {
                 p.setPrice(9.25);
             });

         filteredPeoples.stream()
             .filter(p -> p.hasCoupon())
             .forEach(p -> {
                 p.setPrice(p.getPrice() - 2.00);
             });


Regards, Peter


On 04/09/2013 12:59 PM, Peter Levart wrote:
> On 04/09/2013 01:35 AM, Barry Burd wrote:
>> The following code seems very repetitious to me. Ss there a 
>> recommended way to refactor this code?
>>        people.parallelStream()
>>        .filter(p -> p.getAge() >= 12)
>>        .filter(p -> p.getAge() < 65)
>>        .forEach(p -> {
>>          p.setPrice(9.25);
>>        });
>>           people.parallelStream()
>>        .filter(p -> p.getAge() >= 12)
>>        .filter(p -> p.getAge() < 65)
>>        .filter(p -> p.hasCoupon())
>>        .forEach(p -> {
>>          p.setPrice(p.getPrice() - 2.00);
>>        });
>>        people.parallelStream()
>>        .filter(p -> (p.getAge() < 12 || p.getAge() >= 65))
>>        .forEach(p -> {
>>          p.setPrice(5.25);
>>        });
>>           people.stream()
>>        .forEach(p -> {
>>          p.display();
>>        });
>>           people.stream().map(p -> p.getPrice()).forEach(amount -> 
>> total += amount);
>>
>
> It depends what DRY means: Don't repead yourself (dont write exact 
> same code twice or more times) or Don't make CPU repeat itself (don't 
> make CPU execute the same code twice or more times unless it's 
> necessary).
>
> For the 1st DRY meaning (and I don't mean the 2nd is less important), 
> you could "capture" the code into a reusable block:
>
>
>         UnaryOperator<Stream<Person>> commonOps = (stream) ->
>             stream
>                 .filter(p -> p.getAge() >= 12)
>                 .filter(p -> p.getAge() < 65);
>
>         commonOps
>             .apply(people.parallelStream())
>             .forEach(p -> {
>                 p.setPrice(9.25);
>             });
>
>         commonOps
>             .apply(people.parallelStream())
>             .filter(p -> p.hasCoupon())
>             .forEach(p -> {
>                 p.setPrice(p.getPrice() - 2.00);
>             });
>
> ...
>
> The above works, but would look fancier if j.u.s.Stream implemented 
> the following default methods:
>
>
>     default <U> Stream<U> transform(Function<Stream<T>, Stream<U>> 
> function) {
>         return function.apply(this);
>     }
>
>     default DoubleStream transformToDouble(Function<Stream<T>, 
> DoubleStream> function) {
>         return function.apply(this);
>     }
>
>     default LongStream transformToLong(Function<Stream<T>, LongStream> 
> function) {
>         return function.apply(this);
>     }
>
>     default IntStream transformToInt(Function<Stream<T>, IntStream> 
> function) {
>         return function.apply(this);
>     }
>
>
> With those methods, you could write:
>
>
>         UnaryOperator<Stream<Person>> commonOps = (stream) ->
>             stream
>                 .filter(p -> p.getAge() >= 12)
>                 .filter(p -> p.getAge() < 65);
>
>         people.parallelStream()
>             .transform(commonOps)
>             .forEach(p -> {
>                 p.setPrice(9.25);
>             });
>
>         people.parallelStream()
>             .transform(commonOps)
>             .filter(p -> p.hasCoupon())
>             .forEach(p -> {
>                 p.setPrice(p.getPrice() - 2.00);
>             });
>
>
> Regards, Peter
>
>
>



More information about the lambda-dev mailing list