amaembo / streamex

Enhancing Java Stream API
Apache License 2.0
2.18k stars 250 forks source link

Added mapInstance method to StreamEx #182

Closed gm2211 closed 4 years ago

gm2211 commented 6 years ago

This can be useful in a few instances, but especially when processing sub-classes of some type which one does not control (and therefore the visitor pattern cannot be used).

List<ColumnProcessor> columnProcessors = ...

List<ColumnProcessingBehavior> behaviors = StreamEx.of(columnProcessors)
      .mapInstance(DateTimeColumnProcessor.class, proc -> proc.dropsTime() ? DROP_TIME : ORIGINAL)
      .mapInstance(StringSplittingColumnProcessor.class, proc -> isComma(proc.getDelimiter()) ? SPLIT_ON_COMMA : UNKNOWN)
      .selectOrDefault(ColumnProcessingBehavior.class, UNKNOWN)
      .toImmutableList();

instead of

List<ColumnProcessor> columnProcessors = ...

List<ColumnProcessingBehavior> behaviors = StreamEx.of(columnProcessors)
      .map(proc -> {
           if (proc instanceof DateTimeColumnProcessor) {
                return ((DateTimeColumnProcessor) proc).dropsTime() ? DROP_TIME : ORIGINAL;
           } else if (proc instanceof StringSplittingColumnProcessor) {
                return isComma(((StringSplittingColumnProcessor.class) proc).getDelimiter())) 
                           ? SPLIT_ON_COMMA 
                           : UNKNOWN;
           }
           return UNKNOWN;
       }).select(ColumnProcessingBehavior.class)
          .toImmutableList();
coveralls commented 6 years ago

Coverage Status

Coverage increased (+0.04%) to 98.665% when pulling c42a6c1eeb9b1824fa7232093d358179573ac87f on gm2211:gm/map-instance into bcdec3153f6deb34901ea1767c76ff2ffba57aca on amaembo:master.

loordgek commented 6 years ago

there are a lot of formatting changes that clutters up the pr

gm2211 commented 6 years ago

My IDE automatically strips out trailing whitespaces - but I can revert those changes

gm2211 commented 6 years ago

@amaembo I can't really say what belongs to StreamEx and what doesn't, but what I know is that Java unfortunately does not have dynamic dispatch based on method signature, nor pattern matching and if you do not control a certain data type, you can't really use the visitor pattern (unless you create your own mirrored copy of the type and convert first), in which case the pattern proposed in this PR seemed reasonable.

amaembo commented 4 years ago

I'm sorry but I finally decided to decline this. Essentially all the suggested enhancements could be trivially implemented with existing map operation. The proposed mapIsInstance will be superseded in future Java versions with switch expression (already released in Java 14)+type matching (hopefully will be here a few years later). Even now it's possible to write it as a sequence of plain old if statements. Creating a separate API method for every possible conditional chain inside map lambda is out of the scope of StreamEx.

gm2211 commented 4 years ago

@amaembo I completely agree - I should have closed this PR a while ago