简体   繁体   中英

How to simulate obj-c blocks in Java as Lambdas?

The pattern below works a little bit like Obj-C's blocks. I'm wondering if it's possible to re-write this using java 8's Lambdas. And if did so, would executing the lambda span a new thread, or would it run within the same thread?

private interface RunnableBlock {
    public void runA(MyObj myObj);
    public void runB(MyObj myObj);
}

// frequently used method
private MyObj operateOnMyObj(short someParams, RunnableBlock runnableBlock) throws Exception {
    // do a lot of stuff... 

    // MyObj is generated here
    MyObj myObj = // blah blah..

    if(myCondition) {
        //common pre-runnable
        runnableBlock.runA(myObj);
        //common post-runnable
    } else {
        //other common pre-runnable
        runnableBlock.runB(myObj);
        //other common post-runnable
    }
    return myObj;
}

public void aMyObjConsumer() {
    // now to use the above
    MyObj myObj = operateOnMyObj(someParam,
        new RunnableBlock() {
            @Override public void runA(MyObj myObj) {
                // do stuff..
            }

            @Override public void runB(MyObj myObj) {
                // do different stuff.. 
            }
        }
    );
}

I don't know Objective-C, but I guess you want to run two different pieces of code depending on some condition, passed as a lambda expression? That would not work in Java.

Lambdas can only be used where a Functional Interface is required. Functional interfaces have exactly one abstract method. So you'd have to split your runnableBlock into two arguments. Consumer seems to be the appropriate interface from the standard library.

Anyways, it would not spawn a new thread. Lambdas are just syntactic replacements for anonymous implementations of functional interfaces. They are not inherently related to multithreading.


Example code (shortened):

// frequently used method
private MyObj operateOnMyObj(Consumer<MyObj> block1, Consumer<MyObj> block2 {
    // ...
    if (myCondition) {
        block1.accept(myObj);
    } else {
        block2.accept(myObj);
    }
    return myObj;
}

public void aMyObjConsumer() {
    // now to use the above
    MyObj myObj = operateOnMyObj((myObj) -> { /* do stuff */ }, (myObj) -> { /* do different stuff */ });
}

I assumed menu was a typo and should read runnableBlock , since runB is not used anywhere else.

Again, I don't know how it would work in Objective-C, but in Java it looks kind of awkward.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM