java 流 Java 7

java streams in Java 7

我的问题可能太宽泛了,答案可能很简单,但我不得不问。

Java 7 中是否有 (Java 8) streams* 的等效实现?

我熟悉 (Java 8) 流,但我的项目要求是使用 Java 7.

*不要与 inputStream and outputStream 混淆。

Google 的 Guava 库包含 一些 功能习语 Java 版本 5 到 7:

https://github.com/google/guava/wiki/FunctionalExplained

此外,还有一个您可能想要查看的库(直到几分钟前我执行 Google 搜索时才听说过它 :-))

http://www.functionaljava.org/

在官方API中,没有。

public 没有更多 Java 7 的更新。如果您是客户,您可能仍会获得次要更新,但这不会(或非常非常不可能)用于支持-移植流 API.

稍加挖掘,您可能会看到 StreamSupport. I've never tested it but apparently its goal is to backport the Stream API to Java 6/7 and if you want to combine it with lambda expressions there's also retrolambda

Functional Java can be interesting. It's not exactly the same intent as the Stream API but if your goal is to filter/map/etc. a list/array it might suits your needs. For example:

final List<Integer> b = list(1, 2, 3).map(add.f(-1));
listShow(intShow).println(b); // [0, 1, 2]

您终于可以查看 Scala 的 Stream API。由于 Scala 也在 JVM 上运行,因此您可以混合使用您的代码。也许这不是您要找的东西,但如果需要,值得一试。

这里还有一个选择 Java 6+

接口:

interface TransformRule<In, Out> {
    Out extract(In obj);
}

interface FilterRule<T> {
    boolean apply(T obj);
}

和 Java8 类流容器 class for Collection/Map:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

class FPMapContainer<KeyType, ValueType> extends FPContainer<Map<KeyType, ValueType>, Map.Entry<KeyType, ValueType>, ValueType> {
    FPMapContainer(Map<KeyType, ValueType> container) {
        super(container);
    }

    @Override
    public <Out> FPMapContainer<KeyType, Out> map(TransformRule<Map.Entry<KeyType, ValueType>, Out> rule) {
        return new FPMapContainer<>(handleContainer(getMapMapRule(rule)));
    }

    @Override
    public FPMapContainer<KeyType, ValueType> filter(FilterRule<Map.Entry<KeyType, ValueType>> rule) {
        return new FPMapContainer<>(handleContainer(getMapFilterRule(rule)));
    }

    @Override
    public FPMapContainer<KeyType, ValueType> concat(Map<KeyType, ValueType> another) {
        HashMap newOne = new HashMap(container);
        newOne.putAll(another);
        return new FPMapContainer<>(newOne);
    }

    @Override
    public FPMapContainer<KeyType, ValueType> concat(FPContainer<Map<KeyType, ValueType>, Map.Entry<KeyType, ValueType>, ValueType> another) {
        return concat(another.get());
    }

    protected <Out> TransformRule<Map<KeyType, ValueType>, Map<KeyType, Out>> getMapMapRule(final TransformRule<Map.Entry<KeyType, ValueType>, Out> rule) {
        return new TransformRule<Map<KeyType, ValueType>, Map<KeyType, Out>>() {
            @Override
            public Map<KeyType, Out> extract(Map<KeyType, ValueType> obj) {
                Map<KeyType, Out> newOne = new HashMap<>();
                for (Map.Entry<KeyType, ValueType> entry : obj.entrySet()) {
                    newOne.put(entry.getKey(), rule.extract(entry));
                }
                return newOne;
            }
        };
    }

    protected TransformRule<Map<KeyType, ValueType>, Map<KeyType, ValueType>> getMapFilterRule(final FilterRule<Map.Entry<KeyType, ValueType>> rule) {
        return new TransformRule<Map<KeyType, ValueType>, Map<KeyType, ValueType>>() {
            @Override
            public Map<KeyType, ValueType> extract(Map<KeyType, ValueType> obj) {
                Map<KeyType, ValueType> newOne = new HashMap<>();
                for (Map.Entry<KeyType, ValueType> 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<ValueType> extends FPContainer<Collection<ValueType>, ValueType, ValueType> {
    FPCollectionContainer(Collection<ValueType> container) {
        super(container);
    }

    @Override
    public <Out> FPCollectionContainer<Out> map(TransformRule<ValueType, Out> rule) {
        return new FPCollectionContainer<>(handleContainer(getCollectionMapRule(rule)));
    }

    @Override
    public FPCollectionContainer<ValueType> filter(FilterRule<ValueType> rule) {
        return new FPCollectionContainer<>(handleContainer(getCollectionFilterRule(rule)));
    }

    @Override
    public FPCollectionContainer<ValueType> concat(Collection<ValueType> another) {
        ArrayList<ValueType> newOne = new ArrayList<>(container);
        newOne.addAll(another);
        return new FPCollectionContainer<>(newOne);
    }

    @Override
    public FPCollectionContainer<ValueType> concat(FPContainer<Collection<ValueType>, ValueType, ValueType> another) {
        return concat(another.get());
    }

    protected <Out> TransformRule<Collection<ValueType>, Collection<Out>> getCollectionMapRule(final TransformRule<ValueType, Out> rule) {
        return new TransformRule<Collection<ValueType>, Collection<Out>>() {
            @Override
            public Collection<Out> extract(Collection<ValueType> obj) {
                Collection<Out> newOne = new ArrayList<>();
                for (ValueType entry : obj) {
                    newOne.add(rule.extract(entry));
                }
                return newOne;
            }
        };
    }

    protected TransformRule<Collection<ValueType>, Collection<ValueType>> getCollectionFilterRule(final FilterRule<ValueType> rule) {
        return new TransformRule<Collection<ValueType>, Collection<ValueType>>() {
            @Override
            public Collection<ValueType> extract(Collection<ValueType> obj) {
                Collection<ValueType> newOne = new ArrayList<>();
                for (ValueType entry : obj) {
                    if (rule.apply(entry)) {
                        newOne.add(entry);
                    }
                }
                return newOne;
            }
        };
    }
}

abstract class FPContainer<ContainerTypeWithValueType, ContainerIterableItemType, ValueType> {

    protected ContainerTypeWithValueType container;

    protected FPContainer(ContainerTypeWithValueType container) {
        this.container = container;
    }

    public static <KeyType, ValueType> FPMapContainer<KeyType, ValueType> from(Map<KeyType, ValueType> container) {
        return new FPMapContainer<>(container);
    }

    public static <ValueType> FPCollectionContainer<ValueType> from(Collection<ValueType> container) {
        return new FPCollectionContainer<>(container);
    }

    public abstract <Out> Object map(TransformRule<ContainerIterableItemType, Out> rule);

    public abstract FPContainer<ContainerTypeWithValueType, ContainerIterableItemType, ValueType> filter(FilterRule<ContainerIterableItemType> rule);

    public abstract FPContainer<ContainerTypeWithValueType, ContainerIterableItemType, ValueType> concat(FPContainer<ContainerTypeWithValueType, ContainerIterableItemType, ValueType> another);

    public abstract FPContainer<ContainerTypeWithValueType, ContainerIterableItemType, ValueType> concat(ContainerTypeWithValueType another);

    public <Out> Out reduce(TransformRule<ContainerTypeWithValueType, Out> rule) {
        return rule.extract(container);
    }

    public ContainerTypeWithValueType get() {
        return container;
    }

    protected <ContainerTargetType> ContainerTargetType handleContainer(TransformRule<ContainerTypeWithValueType, ContainerTargetType> collectionMapRule) {
        if (collectionMapRule != null) {
            return collectionMapRule.extract(container);
        }

        return (ContainerTargetType) container;
    }
}

现在您可以像 Java8Stream 那样使用它了:

TransformRule<Integer, String> integerStringTransform = new TransformRule<Integer, String>() {
    @Override
    public String extract(Integer obj) {
        return "" + obj;
    }
};

TransformRule<Collection<String>, String> collectionStringTransform = new TransformRule<Collection<String>, String>() {
    @Override
    public String extract(Collection<String> obj) {
        String result = "";
        for (String item : obj) {
            result += item;
        }

        return result;
    }
};

FilterRule<Integer> ltFourFilter = new FilterRule<Integer>() {
    @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<Map.Entry<String, Integer>>() {
            @Override
            public boolean apply(Map.Entry<String, Integer> obj) {
                return obj.getKey().charAt(0) < 'c' && obj.getValue() < 4;
            }
        })
        .map(new TransformRule<Map.Entry<String,Integer>, String>() {
            @Override
            public String extract(Map.Entry<String, Integer> obj) {
                return ""+obj.getValue();
            }
        }).reduce(new TransformRule<Map<String, String>, String>() {
            @Override
            public String extract(Map<String, String> obj) {
                String result = "";

                Map<String, String> objectStringMap = sortByValue(obj);
                for (Map.Entry<String, String> entry : objectStringMap.entrySet()) {
                    result += entry.getKey().toString() + entry.getValue();
                }

                return result;
            }
        });

P.S.

sortByValue(map) 在这里:(来源:)

public static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
    List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Object>() {
        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
        }
    });

    Map<K, V> result = new LinkedHashMap<>();
    for (Iterator<Map.Entry<K, V>> it = list.iterator(); it.hasNext();) {
        Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}