代码之家  ›  专栏  ›  技术社区  ›  sprinter

强制终端操作

  •  2
  • sprinter  · 技术社区  · 7 年前

    我有一个访问者,它返回一个泛型类型以提供灵活性:

    interface Base {
        default <T> Stream<T> accept(Visitor<T> visitor) {
            return visitor.visit(this).stream();
        }
    }
    
    class Sub implements Base {
        <T> Stream<T> accept(Visitor<T> visitor) {
            return Stream.concat(super.accept(visitor), visitor.visit(this).stream());
        }
    }
    
    interface Visitor<T> {
        default Optional<T> visit(Base base) { 
            return Optional.empty() 
        }
    
        default Optional<T> visit(Sub sub){ 
            return Optional.empty() 
        }
    }
    

    <T> Stream<T> visitAll(Visitor<T> visitor) {
        return getStream().flatMap(o -> o.accept(visitor));
    }
    

    当访问者返回一个值时,这一点非常有效:

    visitAll(new Visitor<Sub>() {
        Optional<Sub> visit(Sub sub) {
            return Optional.of(sub);
        }
    }).forEach(...);
    

    当它用于不返回值的访问者时,就会出现问题:

    visitAll(new Visitor<Void>() {
        Optional<Void> visit(Sub sub) {
            // do something with sub
            return Optional.empty();
        }
    });
    

    一种可能的解决方案是强制终端操作:

    <T> Stream<T> visitAll(Visitor<T> visitor) {
        return getStream()
            .collect(Collectors.toList()).stream()
            .flatMap(o -> o.accept(visitor));
    }
    

    另一种解决方案是始终使用以下值:

    visitAll(new Visitor<Void>() {
        Optional<Void> visit(Sub sub) {
            // do something with sub
            return Optional.empty();
        }
    }).findAny();
    

    有没有更优雅的方法来强制流上的终端操作?或者有没有其他的设计可以避免这个问题?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Sean Van Gorder    7 年前

    我会做两个版本的 visitAll ,一个返回流,另一个终止流而不返回任何内容。

    <T> Stream<T> visitAllStream(Visitor<T> visitor) {
        return getStream().flatMap(o -> o.accept(visitor));
    }
    
    void visitAll(Visitor<?> visitor) {
        getStream().forEach(o -> o.accept(visitor));
    }
    

    这样你就只能用 visitAllStream 当你要对结果做进一步的操作时。你还是要确保你不使用 访问流 维斯塔尔 ,但这会使错误更加明显。

    推荐文章