Using visitor pattern instead of casting : <p>I make regular use of the visitor pattern in my code. When a class hierarchy has a visitor implemented, I use it as an alternative to <code>instanceof</code> and casting. However it leads to some pretty awkward code which I'd like to improve.</p>

<p>Consider the contrived case:</p>

<pre><code>interface Animal {
    void accept(AnimalVisitor visitor);
}

class Dog implements Animal {
    void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }
}

class Cat implements Animal {
    void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }
}

interface AnimalVisitor {
    default void visit(Cat cat) {};
    default void visit(Dog dog) {};
}
</code></pre>

<p>In the majority of cases, to do something specific to dogs only (for example) I implement a visitor that implements the logic in its <code>visit</code> method - just as the pattern intends.</p>

<p>There are case, however, in which I want to return an optional dog from the visitor to use outside.</p>

<p>In these case I end up with some pretty ugly code:</p>

<pre><code>List&lt;Dog&gt; dogs = new ArrayList&lt;&gt;();
animal.accept(new AnimalVisitor() {
    void visit(Dog dog) {
        dogs.add(dog);
    }
}
Optional&lt;Dog&gt; possibleDog = dogs.stream().findAny();
</code></pre>

<p>I can't assign <code>possibleDog</code> directly inside the visitor because it's not a final variable, hence the list. </p>

<p>This is pretty ugly and inefficient just to get around requirement for effective finality. I'd be interested in ideas of alternatives. </p>

<p>Alternatives I've considered:</p>

<p>Turning the visitor into a generic which can be given a return value</p>

<pre><code>interface Animal {
    &lt;T&gt; T accept(AnimalVisitor&lt;T&gt; visitor);
}

interface AnimalVisitor &lt;T&gt; {
    default Optional&lt;T&gt; visit(Dog dog) { return Optional.empty(); }
    default Optional&lt;T&gt; visit(Cat cat) { return Optional.empty(); }
}
</code></pre>

<p>Creating an abstract visitor that contains most of the code and can be trivial extended to set the optional directly</p>

<pre><code>abstract class AnimalCollector implements AnimalVisitor &lt;T&gt; {
    private Optional&lt;T&gt; result = Optional.empty;

    protected void setResult(T value) {
        assert !result.isPresent();
        result = Optional.of(value);
    }

    public Optional&lt;T&gt; asOptional() {
        return result;
    }
}
</code></pre>

<p>Use a stream builder instead of a list</p>

<pre><code>Stream.Builder&lt;Dog&gt; dogs = Stream.builder();
animal.accept(new AnimalVisitor() {
    void visit(Dog dog) {
        dogs.accept(dog);
    }
}
Optional&lt;Dog&gt; possibleDog = dogs.build().findAny();
</code></pre>

<p>But I don't find these particularly elegant. They involve a lot of boilerplate just to implement basic <code>asA</code> logic. I tend to use the second solution in my code to keep the usage clean. Is there a simpler solution I'm missing?</p>

<p>Just to be clear, I'm not that interested in answers with some variant of "use instanceof and casts". I realise it would work in this trivial case but the situations I'm considering have quite complex use of visitors that include visiting composites and delegates which make casting impractical. </p>
