【问题标题】:Java8: Using an IntStream as a Supplier parameter for custom CollectorJava8:使用 IntStream 作为自定义收集器的供应商参数
【发布时间】:2018-10-14 00:23:44
【问题描述】:

对于流对象,是不是不能用collect方法写一个自定义的Collector对象,然后收集到另一个流对象?我最近刚刚了解了流,并试图获得尽可能多的经验,但我遇到了这个问题。

我的代码是:

    // method to return how many unique letters are used in
    // the Strings in the given stream
    public int uniqueLetters(Stream<String> stream){
        // transfer Strings to an uppercase char stream
        IntStream allLets = stream.collect(IntStream::empty, 
                          (s1, s2) -> { String toAdd = s2.toUpperCase();
                                        IntStream cs = toAdd.chars();
                                        IntStream.concat(s1, cs); //exception thrown on this line
                                       }, IntStream::concat); 
        // use distinct on char stream and count
        return (int) allLets.distinct().count();
    }

此代码编译并且 collect 方法对于流中的第一个 String 运行良好,但第二次到达 IntStream.concat(s1, cs) 我得到以下异常:

java.lang.IllegalStateException: 流已经被操作或关闭

我的解释是,一旦我的第一个 String 转换为 IntStream 并且 collect 方法移动到下一个 String,我的第一个 IntStream 就会关闭。那是对的吗?为什么会这样?

这是我为自己发明的一个练习,旨在获得更多关于流和函数式编程的经验。我知道这可能不是编写此方法的最佳方式。我有兴趣知道为什么这不起作用,而不是我可以采取什么其他方法。

【问题讨论】:

    标签: java java-8 functional-programming java-stream collectors


    【解决方案1】:

    通过调用concat,您并没有改变s1concat 返回连接的流。流首先是不可变的。

    这意味着你开始使用的Stream.empty 从未改变过,它在concat 方法中一次又一次地使用。但是,您不能concat 中使用流两次。这算作“在流上操作”。因此,当您第二次尝试执行此操作时,您会得到记录在案的非法状态异常:

    应该对流进行操作(调用中间或终端 流操作)只有一次。例如,这排除了“分叉” 流,其中相同的源为两个或多个管道提供数据,或者 同一流的多次遍历。流实现可以 如果检测到流正在被抛出,则抛出 IllegalStateException 重复使用。但是,由于某些流操作可能会返回它们的 接收器而不是新的流对象,可能无法 在所有情况下检测重用。

    为了解决您寻找独特角色的问题,您无需收集到流。只需这样做:

    public static int uniqueLetters(Stream<String> stream){
        return (int)stream.flatMapToInt(String::chars).distinct().count();
    }
    

    flatMap 可能是您通过收集到流来尝试做的事情。现在你知道这叫flatMap

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多