Java 类似于 IntStream 的静态构建
Java static build similar to IntStream
我的目标是提供一个 class 来构建一个函数链来执行一些任务。这是我到目前为止能想到的
函数class
public class Loop {
private final int from;
private final int to;
private Loop(int from, int to) {
this.from = from;
this.to = to;
}
public static Loop from(int from) {
return new Loop(from, 0);
}
public static Loop to(int to) {
return new Loop(0, to);
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
}
可执行界面
@FunctionalInterface
public interface Executable {
void execute();
}
它可以对一个参数(从或到)起作用,例如
Loop.to(10).execute(() -> {});
但我希望它适用于多个参数,例如
Loop.from(5).to(10).execute(() -> {});
我怎样才能做到这一点?此外,我不确定 static from 和 static to 方法是否适合 Loop class 以及一个冗余参数。
如果 from
和 non-static 的静态变体具有相同的名称,那将是理想的选择,但这不受支持。参数或名称必须不同。
因此,我将创建私有构造函数 public 并添加第二个 no-args 构造函数,以便调用可以变为:
new Loop().from(5).to(10).execute(...)
new Loop(5, 10).execute(...)
要使其正常工作,from
和 to
必须不再是静态的。然后你必须决定这些方法是否改变了它们被调用的 Loop
实例,或者它们是否 return 一个新对象:
public Loop from(int from) {
return new Loop(from, to);
}
public Loop to(int to) {
return new Loop(from, to);
}
或
public Loop from(int from) {
this.from = from; // no longer final
return this;
}
public Loop to(int to) {
this.to = to; // no longer final
return this;
}
如果您想更进一步,您可以将 class 重命名为 LoopBuilder
并创建一个 build()
方法,该方法 return 是一个 Loop
具有字段和以前一样,但没有 from
和 to
方法,只有 execute
方法:
public static class Loop {
private final int from;
private final int to;
public Loop(int from, int to) {
this.from = from;
this.to = to;
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
public static LoopBuilder builder() {
return new LoopBuilder();
}
}
public static class LoopBuilder {
private int from;
private int to;
public LoopBuilder from(int from) {
this.from = from;
return this;
}
public LoopBuilder to(int to) {
this.to = to;
return this;
}
public Loop build() {
return new Loop(from, to);
}
}
调用将变成
Loop.builder().from(5).to(10).build().execute(...);
可以采用多种方法。解决方案越复杂,它们通常就越复杂。让我们从一个简单的解决方案开始。
public class Loop {
private final int from;
private final int to;
private Loop(Builder builder) {
this.from = builder.from();
this.to = builder.to();
}
public static Builder from(int from) {
return new Builder().from(from);
}
public static Builder to(int to) {
return new Builder().to(to);
}
public void execute(Runnable executable) {
for (int i = from; i < to; i++) {
executable.run();
}
}
public static class Builder {
private int from = 0;
private Integer to = null;
private Builder() {}
public Builder from(int from) {
this.from = from;
return this;
}
private int from() {
return from;
}
public Builder to(int to) {
this.to = to;
return this;
}
private int to() {
return to;
}
public void execute(Runnable runnable) {
Objects.requireNonNull(runnable);
new Loop(this).execute(runnable);
}
}
}
这已经很了不起了。但是我们可以,例如,多次调用 from(...)
或 to(...)
。如果我们只允许调用 from(...)
一次,之后只允许调用 to(...)
,那么我们需要定义更多类型。我们可以通过添加接口 LoopFromSetBuilder
、LoopToSetBuilder
和 LoopAllSetBuilder
:
来实现这一点
interface LoopFromSetBuilder {
LoopAllSetBuilder to(int to);
}
interface LoopToSetBuilder {
LoopAllSetBuilder from(int from);
}
interface LoopAllSetBuilder {
void execute(Runnable runnable);
}
加上方法上的一些小调整 Loop
class Loop {
...
public static LoopFromSetBuilder from(int from) {
return new Builder().from(from);
}
public static LoopToSetBuilder to(int to) {
return new Builder().to(to);
}
...
}
并让 Builder
实现这些接口:
public static class Builder implements LoopFromSetBuilder, LoopToSetBuilder, LoopAllSetBuilder {
...
}
我们消除了用户多次调用 from(...)
和 to(...)
的可能性。
我没有进一步构建那些“复杂”的流利 API 的经验,但我想构建这样一个 API 的过程会非常痛苦。对于小例子,就像这里一样,我们可能能够拒绝多次设置相同的变量,但是使用更多参数似乎很混乱(可能的状态 - 因此 - 接口似乎是 2^n
的顺序,其中 n
是字段数...所以是的。
如果有人赞成我的答案,也应该考虑赞成 ,因为我的答案的第一个解决方案与 Luk2302 的解决方案非常相似,而且 Luk2302 的答案发布时间比我的早一点。
我的目标是提供一个 class 来构建一个函数链来执行一些任务。这是我到目前为止能想到的
函数class
public class Loop {
private final int from;
private final int to;
private Loop(int from, int to) {
this.from = from;
this.to = to;
}
public static Loop from(int from) {
return new Loop(from, 0);
}
public static Loop to(int to) {
return new Loop(0, to);
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
}
可执行界面
@FunctionalInterface
public interface Executable {
void execute();
}
它可以对一个参数(从或到)起作用,例如
Loop.to(10).execute(() -> {});
但我希望它适用于多个参数,例如
Loop.from(5).to(10).execute(() -> {});
我怎样才能做到这一点?此外,我不确定 static from 和 static to 方法是否适合 Loop class 以及一个冗余参数。
如果 from
和 non-static 的静态变体具有相同的名称,那将是理想的选择,但这不受支持。参数或名称必须不同。
因此,我将创建私有构造函数 public 并添加第二个 no-args 构造函数,以便调用可以变为:
new Loop().from(5).to(10).execute(...)
new Loop(5, 10).execute(...)
要使其正常工作,from
和 to
必须不再是静态的。然后你必须决定这些方法是否改变了它们被调用的 Loop
实例,或者它们是否 return 一个新对象:
public Loop from(int from) {
return new Loop(from, to);
}
public Loop to(int to) {
return new Loop(from, to);
}
或
public Loop from(int from) {
this.from = from; // no longer final
return this;
}
public Loop to(int to) {
this.to = to; // no longer final
return this;
}
如果您想更进一步,您可以将 class 重命名为 LoopBuilder
并创建一个 build()
方法,该方法 return 是一个 Loop
具有字段和以前一样,但没有 from
和 to
方法,只有 execute
方法:
public static class Loop {
private final int from;
private final int to;
public Loop(int from, int to) {
this.from = from;
this.to = to;
}
public void execute(Executable executable) {
for (int i = from; i < to; i++) {
executable.execute();
}
}
public static LoopBuilder builder() {
return new LoopBuilder();
}
}
public static class LoopBuilder {
private int from;
private int to;
public LoopBuilder from(int from) {
this.from = from;
return this;
}
public LoopBuilder to(int to) {
this.to = to;
return this;
}
public Loop build() {
return new Loop(from, to);
}
}
调用将变成
Loop.builder().from(5).to(10).build().execute(...);
可以采用多种方法。解决方案越复杂,它们通常就越复杂。让我们从一个简单的解决方案开始。
public class Loop {
private final int from;
private final int to;
private Loop(Builder builder) {
this.from = builder.from();
this.to = builder.to();
}
public static Builder from(int from) {
return new Builder().from(from);
}
public static Builder to(int to) {
return new Builder().to(to);
}
public void execute(Runnable executable) {
for (int i = from; i < to; i++) {
executable.run();
}
}
public static class Builder {
private int from = 0;
private Integer to = null;
private Builder() {}
public Builder from(int from) {
this.from = from;
return this;
}
private int from() {
return from;
}
public Builder to(int to) {
this.to = to;
return this;
}
private int to() {
return to;
}
public void execute(Runnable runnable) {
Objects.requireNonNull(runnable);
new Loop(this).execute(runnable);
}
}
}
这已经很了不起了。但是我们可以,例如,多次调用 from(...)
或 to(...)
。如果我们只允许调用 from(...)
一次,之后只允许调用 to(...)
,那么我们需要定义更多类型。我们可以通过添加接口 LoopFromSetBuilder
、LoopToSetBuilder
和 LoopAllSetBuilder
:
interface LoopFromSetBuilder {
LoopAllSetBuilder to(int to);
}
interface LoopToSetBuilder {
LoopAllSetBuilder from(int from);
}
interface LoopAllSetBuilder {
void execute(Runnable runnable);
}
加上方法上的一些小调整 Loop
class Loop {
...
public static LoopFromSetBuilder from(int from) {
return new Builder().from(from);
}
public static LoopToSetBuilder to(int to) {
return new Builder().to(to);
}
...
}
并让 Builder
实现这些接口:
public static class Builder implements LoopFromSetBuilder, LoopToSetBuilder, LoopAllSetBuilder {
...
}
我们消除了用户多次调用 from(...)
和 to(...)
的可能性。
我没有进一步构建那些“复杂”的流利 API 的经验,但我想构建这样一个 API 的过程会非常痛苦。对于小例子,就像这里一样,我们可能能够拒绝多次设置相同的变量,但是使用更多参数似乎很混乱(可能的状态 - 因此 - 接口似乎是 2^n
的顺序,其中 n
是字段数...所以是的。
如果有人赞成我的答案,也应该考虑赞成