java streams in Java 7

后端 未结 3 1287
[愿得一人]
[愿得一人] 2020-12-03 09:55

My question may be too broad and probably the answer is a simple NO, but I have to ask.

Is there any equivalent implementation of (Java 8) streams* in Java 7?

<
3条回答
  •  一向
    一向 (楼主)
    2020-12-03 10:51

    An another choice is here for Java 6+

    interfaces:

    interface TransformRule {
        Out extract(In obj);
    }
    
    interface FilterRule {
        boolean apply(T obj);
    }
    

    And Java8Stream-like container class for Collection/Map:

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    class FPMapContainer extends FPContainer, Map.Entry, ValueType> {
        FPMapContainer(Map container) {
            super(container);
        }
    
        @Override
        public  FPMapContainer map(TransformRule, Out> rule) {
            return new FPMapContainer<>(handleContainer(getMapMapRule(rule)));
        }
    
        @Override
        public FPMapContainer filter(FilterRule> rule) {
            return new FPMapContainer<>(handleContainer(getMapFilterRule(rule)));
        }
    
        @Override
        public FPMapContainer concat(Map another) {
            HashMap newOne = new HashMap(container);
            newOne.putAll(another);
            return new FPMapContainer<>(newOne);
        }
    
        @Override
        public FPMapContainer concat(FPContainer, Map.Entry, ValueType> another) {
            return concat(another.get());
        }
    
        protected  TransformRule, Map> getMapMapRule(final TransformRule, Out> rule) {
            return new TransformRule, Map>() {
                @Override
                public Map extract(Map obj) {
                    Map newOne = new HashMap<>();
                    for (Map.Entry entry : obj.entrySet()) {
                        newOne.put(entry.getKey(), rule.extract(entry));
                    }
                    return newOne;
                }
            };
        }
    
        protected TransformRule, Map> getMapFilterRule(final FilterRule> rule) {
            return new TransformRule, Map>() {
                @Override
                public Map extract(Map obj) {
                    Map newOne = new HashMap<>();
                    for (Map.Entry entry : obj.entrySet()) {
                        KeyType key = entry.getKey();
                        ValueType value = entry.getValue();
                        boolean isValid = rule.apply(entry);
    
                        if (isValid) {
                            newOne.put(key, value);
                        }
                    }
                    return newOne;
                }
            };
        }
    }
    
    class FPCollectionContainer extends FPContainer, ValueType, ValueType> {
        FPCollectionContainer(Collection container) {
            super(container);
        }
    
        @Override
        public  FPCollectionContainer map(TransformRule rule) {
            return new FPCollectionContainer<>(handleContainer(getCollectionMapRule(rule)));
        }
    
        @Override
        public FPCollectionContainer filter(FilterRule rule) {
            return new FPCollectionContainer<>(handleContainer(getCollectionFilterRule(rule)));
        }
    
        @Override
        public FPCollectionContainer concat(Collection another) {
            ArrayList newOne = new ArrayList<>(container);
            newOne.addAll(another);
            return new FPCollectionContainer<>(newOne);
        }
    
        @Override
        public FPCollectionContainer concat(FPContainer, ValueType, ValueType> another) {
            return concat(another.get());
        }
    
        protected  TransformRule, Collection> getCollectionMapRule(final TransformRule rule) {
            return new TransformRule, Collection>() {
                @Override
                public Collection extract(Collection obj) {
                    Collection newOne = new ArrayList<>();
                    for (ValueType entry : obj) {
                        newOne.add(rule.extract(entry));
                    }
                    return newOne;
                }
            };
        }
    
        protected TransformRule, Collection> getCollectionFilterRule(final FilterRule rule) {
            return new TransformRule, Collection>() {
                @Override
                public Collection extract(Collection obj) {
                    Collection newOne = new ArrayList<>();
                    for (ValueType entry : obj) {
                        if (rule.apply(entry)) {
                            newOne.add(entry);
                        }
                    }
                    return newOne;
                }
            };
        }
    }
    
    abstract class FPContainer {
    
        protected ContainerTypeWithValueType container;
    
        protected FPContainer(ContainerTypeWithValueType container) {
            this.container = container;
        }
    
        public static  FPMapContainer from(Map container) {
            return new FPMapContainer<>(container);
        }
    
        public static  FPCollectionContainer from(Collection container) {
            return new FPCollectionContainer<>(container);
        }
    
        public abstract  Object map(TransformRule rule);
    
        public abstract FPContainer filter(FilterRule rule);
    
        public abstract FPContainer concat(FPContainer another);
    
        public abstract FPContainer concat(ContainerTypeWithValueType another);
    
        public  Out reduce(TransformRule rule) {
            return rule.extract(container);
        }
    
        public ContainerTypeWithValueType get() {
            return container;
        }
    
        protected  ContainerTargetType handleContainer(TransformRule collectionMapRule) {
            if (collectionMapRule != null) {
                return collectionMapRule.extract(container);
            }
    
            return (ContainerTargetType) container;
        }
    }
    

    Now you can use it like Java8Stream in this way:

    TransformRule integerStringTransform = new TransformRule() {
        @Override
        public String extract(Integer obj) {
            return "" + obj;
        }
    };
    
    TransformRule, String> collectionStringTransform = new TransformRule, String>() {
        @Override
        public String extract(Collection obj) {
            String result = "";
            for (String item : obj) {
                result += item;
            }
    
            return result;
        }
    };
    
    FilterRule ltFourFilter = new FilterRule() {
        @Override
        public boolean apply(Integer obj) {
            return obj != null && obj < 4;
        }
    };
    
    // ==============================================
    
    String reduced;
    
    // Collection case:
    // `reduced` would be "123"
    reduced = FPContainer.from(Arrays.asList(1, 4))
            .concat(FPContainer.from(Arrays.asList(2)))
            .concat(Arrays.asList(3))
            .filter(ltFourFilter)
            .map(integerStringTransform).reduce(collectionStringTransform);
    
    // Map case:
    reduced = FPContainer.from(stringIntegerHashMap)
            .filter(new FilterRule>() {
                @Override
                public boolean apply(Map.Entry obj) {
                    return obj.getKey().charAt(0) < 'c' && obj.getValue() < 4;
                }
            })
            .map(new TransformRule, String>() {
                @Override
                public String extract(Map.Entry obj) {
                    return ""+obj.getValue();
                }
            }).reduce(new TransformRule, String>() {
                @Override
                public String extract(Map obj) {
                    String result = "";
    
                    Map objectStringMap = sortByValue(obj);
                    for (Map.Entry entry : objectStringMap.entrySet()) {
                        result += entry.getKey().toString() + entry.getValue();
                    }
    
                    return result;
                }
            });
    

    P.S.

    sortByValue(map) is here: (credit: https://stackoverflow.com/a/109389/2293635)

    public static  Map sortByValue(Map map) {
        List> list = new LinkedList<>(map.entrySet());
        Collections.sort(list, new Comparator() {
            @SuppressWarnings("unchecked")
            public int compare(Object o1, Object o2) {
                return ((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());
            }
        });
    
        Map result = new LinkedHashMap<>();
        for (Iterator> it = list.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            result.put(entry.getKey(), entry.getValue());
        }
    
        return result;
    }
    
        

    提交回复
    热议问题