Java 8有状态消费者

时间:2016-04-11 22:33:51

标签: java lambda java-8

Java 8中的消费者有条件构成吗?基本上我想创建一个类似于Consumer的自定义Lambda接口,但它只适用于一种类型的对象。我们称之为Stateful,它包含多个状态(为了本示例的目的,我们会说两个):

public class Stateful {
   private int status1;
   private int status2;
}

我们的代码中有很多区域可以对Stateful进行操作,如果状态发生了变化,我们会进行另一个操作。我想知道我们是否可以使用组合以更紧凑和优雅的方式处理它。现在我们会做类似的事情:

SimpleEntry<Integer, Integer> oldStates = new SimpleEntry(stateful.getStatus1(), stateful.getStatus2());

applyLogicOnStateful(stateful); //do some operation that may change state values
if(isStatusChanged(oldStates, stateful) { //compare oldStates integers to status integers
    doSomethingElse(stateful);
}

我认为这样的事情看起来会更好:

statefulConsumer
.accept((stateful)->applyLogicOnStateful(stateful))
.ifStatusChanged((stateful)->doSomethingElse(stateful));

但我不知道我们是否能够跟踪从第一个消费者之前到之后的状态变化。也许我需要创建一个以两个消费者为输入的lambda?

我绝对希望在没有第三方图书馆协助的情况下这样做,不过如果有帮助的话,欢迎你来这里推广。

2 个答案:

答案 0 :(得分:0)

这是一个函数,它将返回一个Consumer<Stateful>,它将提取前一状态,进行更改,比较结果,并有条件地操作已更改的对象。

public static Consumer<Stateful> getStatefulConsumer(
        Function<Stateful,SimpleEntry<Integer,Integer>> getStatus,                  // extract status from Stateful
        Consumer<Stateful> applyLogic,                                              // apply business logic
        BiPredicate<SimpleEntry<Integer,Integer>,SimpleEntry<Integer,Integer>> compareState, // test statuses for change
        Consumer<Stateful> onChange)                                                // doSomethingElse
{
    return stateful -> {
        SimpleEntry<Integer,Integer> oldStatus = getStatus.apply(stateful);
        applyLogic.accept(stateful);
        if(!compareState.test(oldStatus, getStatus.apply(stateful))){
            onChange.accept(stateful);
        }   
    };
}

您可以这样使用它:

Consumer<Stateful> ifChanged = getStatefulConsumer(s -> new SimpleEntry<> ( s.status1, s.status2 ), 
    s -> changeSomething(s), Objects::equals, s->doSomething(s));

您可以对提取的状态进行生成,以便不同的有状态类型可以具有不同的提取状态类型,甚至可以使用Stateful :: clone来复制状态。

答案 1 :(得分:0)

我现在正在使用的解决方案是创建一个Lambda接口,该接口将Stateful实例和两个使用者作为输入:

public interface StatefulConsumer {
    void accept(Stateful stateful, Consumer<Stateful> consumer, Consumer<Stateful> ifStateChangedConsumer);
}

和实施:

final StatefulConsumer IfStateChanges = new StatefulConsumer() {
    @Override
    public void accept(Stateful stateful, Consumer<Stateful> consumer, Consumer<Stateful> ifStateChangedConsumer) {
        SimpleEntry<Integer, Integer> oldStates = new SimpleEntry(stateful.getStatus1(), stateful.getStatus2());

        consumer.accept(stateful); //do some operation that may change state values
        if(isStatusChanged(oldStates, stateful) { //compare oldStates integers to status integers
            ifStateChangedConsumer.accept(stateful);
        }
    }
};

可以像这样调用: IfStateChanges.accept(状态,     (有状态的) - &gt; applyLogicOnStateful(有状态的),     (有状态的) - &gt; doSomethingElse(有状态的))

它也可以实现为谓词或函数,它将有状态和消费者作为输入,并返回一个布尔值,用于if语句