簡體   English   中英

有沒有什么方法可以像消費者一樣簡單地使用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?
}

我怎么能重復上as同時保持b不變,並使用this::doSmallThingdoBigThing

當然以下不起作用。

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有什么簡單的BiConsumer嗎?

你想“綁定”函數參數。 不幸的是,在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對我來說似乎沒問題。 您不應該嘗試使用方法引用來表達所有內容。

在迭代Map條目時使用BiConsumers,例如:

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM