Java Generics: chaining together generic function object

前端 未结 2 1853
轮回少年
轮回少年 2021-02-02 03:23

I\'ve been struggling with the following problem. I have a series of function objects, each with it\'s own input and output types defined via generic type arguments in java. I w

2条回答
  •  庸人自扰
    2021-02-02 03:43

    Here's another way to do it: this way allows for a transformation step to result in a list. For example, a transformation could split a string into multiple substrings. Moreover, it allows for common exception handling code if transforming any of the values produces an exception. It also allows the use of an empty List as a return value instead of an ambiguous null value that has to be tested for to avoid NullPointerException. The main problem with this one is that it does each transformation step in its entirety before moving to the next step, which may not be memory efficient.

    public class Chain {
        private final Chain head;
        private final Transformer tail;
    
        public static  Chain makeHead(@Nonnull Transformer tail) {
            return new Chain<>(null, tail);
        }
    
        public static  Chain append(@Nonnull Chain head, @Nonnull Transformer tail) {
            return new Chain<>(head, tail);
        }
    
        private Chain(@Nullable Chain head, @Nonnull Transformer tail) {
            this.head = head;
            this.tail = tail;
        }
    
        public List run(List input) {
            List allResults = new ArrayList<>();
    
            List headResult;
            if (head == null) {
                headResult = (List) input;
            } else {
                headResult = head.run(input);
            }
    
            for (MEDIAL in : headResult) {
                // try/catch here
                allResults.addAll(tail.transform(in));
            }
    
            return allResults;
        }
    
        public static void main(String[] args) {
    
            Transformer pipe1 = new Transformer() {
                @Override
                public List transform(String s) {
                    return Collections.singletonList(Integer.valueOf(s) * 3);
                }
            };
            Transformer pipe2 = new Transformer() {
                @Override
                public List transform(Integer s) {
                    return Collections.singletonList(s.longValue() * 5);
                }
            };
            Transformer pipe3 = new Transformer() {
                @Override
                public List transform(Long s) {
                    return Collections.singletonList(new BigInteger(String.valueOf(s * 7)));
                }
            };
            Chain chain1 = Chain.makeHead(pipe1);
            Chain chain2 = Chain.append(chain1, pipe2);
            Chain chain3 = Chain.append(chain2, pipe3);
            List result = chain3.run(Collections.singletonList("1"));
            System.out.println(result);
        }
    }
    

提交回复
热议问题