有什么方法可以像Consumers一样简单地使用BiConsumers吗?
Is there any way to use BiConsumers as simply as Consumers?
这只是一个理论问题,没有具体应用。
我有下面的方法,我就不碰了。它可以(如果可能的话)用作 BiConsumer
.
void doSmallThing(A a, B b) {
// do something with a and b.
}
void doBigThing(List<A> as, B b) {
// What to do?
}
如何在保持 b
不变的同时迭代 as
并在 doBigThing
中使用 this::doSmallThing
?
下面当然不行了
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(this::doSmallThing);
}
以下效果很好,实际上是我每天都在使用的。
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(a -> doSmallThing(a, b));
}
以下也很有效,但有点棘手。
Consumer<A> doSmallThingWithFixedB(B b) {
return (a) -> doSmallThing(a, b);
}
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(doSmallThingWithFixedB(b))
}
但是所有这些解决方案都没有 Consumer
案例那么简单。那么 BiConsumer
有什么简单的东西吗?
您想 "bind" 函数参数。不幸的是,在 Java 8 中没有内置机制来执行此操作(除了为 this::
等实例方法绑定对象)。您可以像这样概括您的 doSmallThingWithFixedB
方法:
public class Bind {
public static <A, B> Consumer<A> bindLast(BiConsumer<A, B> fn, B b) {
return a -> fn.accept(a, b);
}
public static <A, B> Consumer<B> bindFirst(BiConsumer<A, B> fn, A a) {
return b -> fn.accept(a, b);
}
}
并使用:
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(Bind.bindLast(this::doSmallThing, b));
}
可能有一些第三方库已经包含了这样的方法。但是,使用显式 lambda 对我来说似乎没问题。你不应该试图用方法引用来表达一切。
BiConsumers 在遍历 Map 条目时使用,例如:
Map<A, B> map = ...;
map.forEach(this::doSomething);
Stream.collect()
也将 BiConsumers 作为参数,但它的使用频率低于映射条目上的迭代。
添加一个方法doSmallThing
到 B:
class B {
public void doSmallThing(A a) {
YourClass.doSmallThing(a, this); // You may want to inline this.
}
}
并从 doBigThing
:
调用它
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(b::doSmallThing);
}
这只是一个理论问题,没有具体应用。
我有下面的方法,我就不碰了。它可以(如果可能的话)用作 BiConsumer
.
void doSmallThing(A a, B b) {
// do something with a and b.
}
void doBigThing(List<A> as, B b) {
// What to do?
}
如何在保持 b
不变的同时迭代 as
并在 doBigThing
中使用 this::doSmallThing
?
下面当然不行了
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(this::doSmallThing);
}
以下效果很好,实际上是我每天都在使用的。
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(a -> doSmallThing(a, b));
}
以下也很有效,但有点棘手。
Consumer<A> doSmallThingWithFixedB(B b) {
return (a) -> doSmallThing(a, b);
}
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(doSmallThingWithFixedB(b))
}
但是所有这些解决方案都没有 Consumer
案例那么简单。那么 BiConsumer
有什么简单的东西吗?
您想 "bind" 函数参数。不幸的是,在 Java 8 中没有内置机制来执行此操作(除了为 this::
等实例方法绑定对象)。您可以像这样概括您的 doSmallThingWithFixedB
方法:
public class Bind {
public static <A, B> Consumer<A> bindLast(BiConsumer<A, B> fn, B b) {
return a -> fn.accept(a, b);
}
public static <A, B> Consumer<B> bindFirst(BiConsumer<A, B> fn, A a) {
return b -> fn.accept(a, b);
}
}
并使用:
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(Bind.bindLast(this::doSmallThing, b));
}
可能有一些第三方库已经包含了这样的方法。但是,使用显式 lambda 对我来说似乎没问题。你不应该试图用方法引用来表达一切。
BiConsumers 在遍历 Map 条目时使用,例如:
Map<A, B> map = ...;
map.forEach(this::doSomething);
Stream.collect()
也将 BiConsumers 作为参数,但它的使用频率低于映射条目上的迭代。
添加一个方法doSmallThing
到 B:
class B {
public void doSmallThing(A a) {
YourClass.doSmallThing(a, this); // You may want to inline this.
}
}
并从 doBigThing
:
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(b::doSmallThing);
}