加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

自定义Java 8收集器

发布时间:2020-12-15 08:27:48 所属栏目:Java 来源:网络整理
导读:我想检查一下如何实现自定义收集器. 说,我需要做一些 (1)对字母频率图和字母等词进行分析 (2)结合2个结果以获得单个结果的能力. class CharHistogram implements CollectorString,MapCharacter,Integer,Integer { public static CharHistogram toCharHistogr
我想检查一下如何实现自定义收集器.

说,我需要做一些

(1)对字母频率图和字母等词进行分析
(2)结合2个结果以获得单个结果的能力.

class CharHistogram implements Collector<String,Map<Character,Integer>,Integer>> {



    public static CharHistogram toCharHistogram(){
        return new CharHistogram();
    }

    @Override
    public Supplier<Map<Character,Integer>> supplier() {
        SysOut.print("supplier invoked");
        return HashMap::new;
    }

    @Override
    public BiConsumer<Map<Character,String> accumulator() {
        SysOut.print("accumulator invoked");
        return (map,val) -> {
            SysOut.print(val +" processed");
            char[] characters = val.toCharArray();
            for (char character : characters) {
                int count = 1;
                if (map.containsKey(character)) {
                    count = map.get(character);
                    count++;
                }
                map.put(character,count);
            }
        };
    }

    @Override
    public BinaryOperator<Map<Character,Integer>> combiner() {
        SysOut.print("combiner invoked");
        return (map1,map2) -> {
            SysOut.print(map1+" merged to "+map2);
            map2.forEach((k,v) -> map1.merge(k,v,(v1,v2) -> v1 + v2));
            return map1;
        };
    }

    @Override
    public Function<Map<Character,Integer>> finisher() {
        SysOut.print("finisher invoked");
        return Function.identity();
    }

    @Override
    public Set<java.util.stream.Collector.Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH,Characteristics.UNORDERED));
    }

}

客户代码:

CharHistogram charStatsState = CharHistogram.toCharHistogram();

Map<Character,Integer> charCountMap = Arrays.asList("apple","orange","orange").stream().collect(charStatsState);
SysOut.print(charCountMap);
charCountMap = Arrays.asList("pears","pears","orange").stream().collect(charStatsState);
SysOut.print(charCountMap);

输出:

[main]: supplier invoked
[main]: accumulator invoked
[main]: combiner invoked
[main]: apple processed
[main]: orange processed
[main]: orange processed
[main]: {p=2,a=3,r=2,e=3,g=2,l=1,n=2,o=2}
[main]: supplier invoked
[main]: accumulator invoked
[main]: combiner invoked
[main]: pears processed
[main]: pears processed
[main]: orange processed
[main]: {p=2,r=3,s=2,g=1,n=1,o=1}

我没有看到组合器和整理器被调用,我相信这些需要正确设计才能实现我正在寻找的东西.

我错过了什么?

编辑:

支持流和组合器的可能方法.以下代码不起作用.

class CharStreamHistogram implements Function<String,Integer>>{

    private int totalCharactersRead;
    private Map<Character,Integer> histogram;

    public int getTotalCharactersRead() {
        return totalCharactersRead;
    }
    public Map<Character,Integer> getHistogram() {
        return histogram;
    }
    public void setHistogram(Map<Character,Integer> histogram) {
        this.histogram = histogram;
    }
    public void setTotalCharactersRead(int totalCharactersRead) {
        this.totalCharactersRead = totalCharactersRead;
    }

    public Map<Character,Integer> combine(Map<Character,Integer>  map2) {
        Map<Character,Integer> map1 = this.histogram;
        map2.forEach((k,v2) -> v1 + v2));
        return map2;
    }


    @Override
    public Map<Character,Integer> apply(String val) {
        char[] characters = val.toCharArray();
        totalCharactersRead += characters.length;
        for (char character : characters) {
            int count = 1;
            if (histogram.containsKey(character)) {
                count = histogram.get(character);
                count++;
            }
            histogram.put(character,count);
        }
        return histogram;
    }

} 

public static <T> Collector<T,?,CharStreamHistogram> summarizeCharStream(
             CharStreamHistogram histogram) { //TODO: is this correct?
        Collector charStatsState = new Collector<String,CharStreamHistogram,CharStreamHistogram>() {

            @Override
            public Supplier<CharStreamHistogram> supplier() {
                return CharStreamHistogram::new;
            }

            @Override
            public BiConsumer<CharStreamHistogram,String> accumulator() {
                //TODO: What to do here?
                return null;
            }

            @Override
            public BinaryOperator<CharStreamHistogram> combiner() {
                BinaryOperator binaryOperator = (l,r) -> {
                    l.combine(r); //TODO: Something like this?
                };
                return binaryOperator;
            }

            @Override
            public Function<CharStreamHistogram,CharStreamHistogram> finisher() {
                //TODO: What to do here?
                return null;
            }

            @Override
            public Set<java.util.stream.Collector.Characteristics> characteristics() {
                return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));
            }
        };
        return charStatsState;
    }

解决方法

那么你已经声明了Characteristics.IDENTITY_FINISH – 这明确意味着不会调用终结器,只有在并行流的情况下才会调用组合器.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读