26

I was using a Stream.Builder and I stumbled upon the fact that this interface has both the methods accept(T t) and add(T t). The only difference is that the former returns void and the latter returns a Stream.Builder.

The documentation even mentions these methods to have the same default implementation:

The default implementation behaves as if:

accept(t)
return this;

Note that they forgot a semicolon, but that's another story.

My question is: why do they have two methods to add something to the stream builder? I think this clutters the API, and I thought they wanted to avoid that.

Is there any compelling reason to do so?

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • 5
    Some static code analyzation tools (IntelliJ in some capacity I reckon, or was it Checkstyle?) complain when you call a method with return type without assigning that return type to a variable, thus the `void` one. And the one with the return type can be used to chain calls in a single line of course. – Smutje Oct 06 '20 at 11:11
  • 7
    `accept` stems from being a `Consumer` and `add` allows the typical chained call (fluent style). – Joop Eggen Oct 06 '20 at 11:24
  • @Sweeper I meant https://docs.oracle.com/javase/10/docs/api/java/util/function/Consumer.html#accept(T) - Conffusion's answer explains it better. – Joop Eggen Oct 06 '20 at 11:31

1 Answers1

35

My guess:

Stream.Builder extends Consumer<T> so it must implement the accept(T) method.

But accept(T) returns void, so I think they added add(T) for convenience: methods in a builder pattern implementation often return this to be able to chain the building and finally call build().

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Conffusion
  • 4,335
  • 2
  • 16
  • 28
  • 3
    Additionally, 'add' is the right name when treating the streambuilder as a builder (I bet if I interview 100 devs about 'what would you call the method on a stream building object, 99 of them would say 'add', and not one would say 'accept'). If you _treat_ that builder as a consumer, then from that quite different viewpoint, 'accept' all of a sudden is sensible. – rzwitserloot Oct 06 '20 at 11:44
  • I see, the `void accept` is inherited from `Consumer`. That makes sense to me. – MC Emperor Oct 06 '20 at 14:43
  • 1
    But for using it as a `Consumer`, it would suffice to do `.callWithConsumer(builder::add)`, no need to make it a `Consumer` in the first place. But they chose to do so, so they must implement it. – glglgl Oct 06 '20 at 20:15