An Interesting Fact Of Java Stream

 

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class MainTest {
    public static void main(String[] args) {

        List<TestObject> testList = new ArrayList<>();
        testList.add(new TestObject("1"));
        testList.add(new TestObject("2"));
        testList.add(new TestObject("3"));
        testList.add(new TestObject("3"));
        testList.add(new TestObject("4"));

        List<String> list = testList.stream()
                .filter(distinctFilter(TestObject::getVal))
                .map(TestObject::getVal)
                .collect(Collectors.toList());

        System.out.println(list);

    }

    private static <T> Predicate<T> distinctFilter(Function<? super T, Object> function) {
        Map<Object,Boolean> valuesHaveBeenSeen = new ConcurrentHashMap<>();
        System.out.println("called once");
        return t -> {
            System.out.println(valuesHaveBeenSeen);
            return valuesHaveBeenSeen.putIfAbsent(function.apply(t), Boolean.TRUE) == null;
        };
    }
}

class TestObject {
    String val;

    public TestObject() {
    }

    public TestObject(String val) {
        this.val = val;
    }

    String getVal() {
        return this.val;
    }
}

Output:

called once
{}
{1=true}
{1=true, 2=true}
{1=true, 2=true, 3=true}
{1=true, 2=true, 3=true}
[1, 2, 3, 4]

It seems the local map valuesHaveBeenSeen is just created once and used throughout the iteration.

 

posted @ 2018-01-19 19:35  小张的练习室  阅读(235)  评论(0编辑  收藏  举报