Java 8 - Consumer's andThen 的使用方法

18

我有以下使用Java 8特性的POC。

我想在接受方法后更新数据库。使用andThen()好吗?这个方法什么时候被调用?谁调用它?

andThen()方法的基本用途是什么?查看文档让人感到困惑。

public class StockTest {

    public static void main(String[] args) {

    List<Trader> traders = new ArrayList<>();

    Random random = new Random();

    // Initializing trading a/c's.
    for (int i = 0; i < 10; i++) {
        Trader trader = new Trader((random.nextInt(100) + 1) * 3);
        traders.add(trader);
    }
    // Display Trade accounts.
    System.out.println("Before Bonus, Units are:");
    for (Trader trader : traders) {
        System.out.print(trader.getUnits() + "\t");
    }

    // Add bonus to each trader.
    traders.forEach(new Consumer<Trader>() {

        @Override
        public void accept(Trader trader) {
            trader.updateBonus(2);
        }

        @Override
        public Consumer<Trader> andThen(Consumer<? super Trader> after) 
       {
            System.out.println("In andThen");
            return Consumer.super.andThen(after);
        }
        });

    // Display Trade accounts after bonus applied..
    System.out.println("\nAfter bonus:");
    for (Trader trader : traders) {
        System.out.print(trader.getUnits() + "\t");
     }

   }

 }

 class Trader {
    private int units;

    public Trader(int initialUnits) {
    this.units = initialUnits;
 }

   public int getUnits() {
        return units;
    }

public void setUnits(int units) {
    this.units = units;
}

 public void updateBonus(int bonusUnits) {
    this.units = this.units * bonusUnits;
  }
 }

请提供一些例子或使用情况,以利用这种方法。

2个回答

10

in short andThen 用于链接多个消费者,因此输入将会传递给第一个和第二个消费者,如下所示:

Consumer<Trader> consumer1 = new Consumer<Trader>() {

    @Override
    public void accept(Trader trader) {
       trader.updateBonus(2);
    }
};

Consumer<Trader> consumer2 = new Consumer<Trader>() {

    @Override
    public void accept(Trader trader) {
       // do something
    }
};
// Add bonus to each trader.
traders.forEach(consumer1.andThen(consumer2));

所以这里交易员将被传递给consumer1,然后传递给consumer2等等。

您无需实现此方法或覆盖它。对于消费者,请仅实现accept方法。

andThen方法是一个帮助工具,用于连接消费者。而不是在循环中将输入传递给所有消费者。


8
当您想要链接两个 Consumer 的逻辑时,使用 andThen consumer1.andThen(consumer2)首先调用 consumer1 accept 方法,然后调用 consumer2 accept 方法。
覆盖 andThen 的默认实现没有太大意义,并且会阻止您使用lambda表达式/方法引用。 andThen 可用于链式两个 Consumer
traders.forEach(((Consumer<Trader>)(trader -> trader.updateBonus(2))).andThen(trader -> System.out.println("some more processing")));

当然,在这个例子中,你可以将两个“Consumer”的逻辑简单地放在一个“Consumer”中:
traders.forEach(trader -> {trader.updateBonus(2);
                           System.out.println("some more processing");});

使用andThen在链接两个现有的Consumer时更加合理。
Consumer<Trader> traderConsumer1 = trader -> trader.updateBonus(2);
Consumer<Trader> traderConsumer2 = trader -> System.out.println(trader);
traders.forEach(traderConsumer1.andThen(traderConsumer2));

2
你不能只写(trader -> trader.updateBonus(2)).andThen(trader -> System.out.println("some more processing")),因为Java无法推断出第一个lambda表达式的类型,因此不知道在哪里搜索andThen方法,也就无法确定第二个lambda表达式的目标类型。 - Holger
1
@Holger 是的,我也不确定,所以进行了测试。我猜你需要将第一个lambda表达式转换为“Consumer<Trader>”。谢谢。 - Eran
4
只有存在现有的消费者时,才使用andThen的另一个原因。 - Holger
1
@Eran,不错。+1。 - Chowdappa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接