/* package whatever; // don't place package name! */
import java.util.*;
import java.util.function.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
// used in both chains
K k1 = new K1();
K k2 = new K2();
// construct A chain
K3A specificA = new K3A();
Function<A, A> handleA = a -> specificA.handle(a);
handleA = handleA.compose(k2::handle);
handleA = handleA.compose(k1::handle);
// try with A
A sampleA = new A();
handleA.apply(sampleA);
// construct B chain
K3B specificB = new K3B();
Function<B,B> handleB = b -> specificB.handle(b);
handleB = handleB.compose(k2::handle);
handleB = handleB.compose(k1::handle);
// try with B
B sampleB = new B();
B result = handleB.apply(sampleB); // you can even get a B result from the whole chain
}
}
interface S {}
class A implements S {}
class B implements S {}
interface K {
<T>T handle(T t);
}
class K1 implements K {
public <T
>T handle
(T t
) { System.
out.
println("K1 handling T"); return t
; } }
class K2 implements K {
public <T
>T handle
(T t
) { System.
out.
println("K2 handling T"); return t
; } }
class K3A implements K {
public A handle
(A a
) { System.
out.
println("K3 handling A"); return a
; } }
class K3B implements K {
public B handle
(B b
) { System.
out.
println("K3 handling B"); return b
; } }
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLio7CmltcG9ydCBqYXZhLmxhbmcuKjsKaW1wb3J0IGphdmEuaW8uKjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CiAgICAgICAgLy8gdXNlZCBpbiBib3RoIGNoYWlucwogICAgICAgIEsgazEgPSBuZXcgSzEoKTsKICAgICAgICBLIGsyID0gbmV3IEsyKCk7CiAgICAgICAgLy8gY29uc3RydWN0IEEgY2hhaW4KICAgICAgICBLM0Egc3BlY2lmaWNBID0gbmV3IEszQSgpOwogICAgICAgIEZ1bmN0aW9uPEEsIEE+IGhhbmRsZUEgPSBhIC0+IHNwZWNpZmljQS5oYW5kbGUoYSk7CiAgICAgICAgaGFuZGxlQSA9IGhhbmRsZUEuY29tcG9zZShrMjo6aGFuZGxlKTsKICAgICAgICBoYW5kbGVBID0gaGFuZGxlQS5jb21wb3NlKGsxOjpoYW5kbGUpOwogICAgICAgIC8vIHRyeSB3aXRoIEEKICAgICAgICBBIHNhbXBsZUEgPSBuZXcgQSgpOwogICAgICAgIGhhbmRsZUEuYXBwbHkoc2FtcGxlQSk7CiAgICAgICAgLy8gY29uc3RydWN0IEIgY2hhaW4KICAgICAgICBLM0Igc3BlY2lmaWNCID0gbmV3IEszQigpOwogICAgICAgIEZ1bmN0aW9uPEIsQj4gaGFuZGxlQiA9IGIgLT4gc3BlY2lmaWNCLmhhbmRsZShiKTsKICAgICAgICBoYW5kbGVCID0gaGFuZGxlQi5jb21wb3NlKGsyOjpoYW5kbGUpOwogICAgICAgIGhhbmRsZUIgPSBoYW5kbGVCLmNvbXBvc2UoazE6OmhhbmRsZSk7CiAgICAgICAgLy8gdHJ5IHdpdGggQgogICAgICAgIEIgc2FtcGxlQiA9IG5ldyBCKCk7CiAgICAgICAgQiByZXN1bHQgPSBoYW5kbGVCLmFwcGx5KHNhbXBsZUIpOyAvLyB5b3UgY2FuIGV2ZW4gZ2V0IGEgQiByZXN1bHQgZnJvbSB0aGUgd2hvbGUgY2hhaW4KCX0KfQoKaW50ZXJmYWNlIFMge30KY2xhc3MgQSBpbXBsZW1lbnRzIFMge30KY2xhc3MgQiBpbXBsZW1lbnRzIFMge30KCmludGVyZmFjZSBLIHsKICAgIDxUPlQgaGFuZGxlKFQgdCk7Cn0KY2xhc3MgSzEgaW1wbGVtZW50cyBLIHsKICAgIHB1YmxpYyA8VD5UIGhhbmRsZShUIHQpIHsgU3lzdGVtLm91dC5wcmludGxuKCJLMSBoYW5kbGluZyBUIik7IHJldHVybiB0OyB9Cn0KCmNsYXNzIEsyIGltcGxlbWVudHMgSyB7CiAgICBwdWJsaWMgPFQ+VCBoYW5kbGUoVCB0KSB7IFN5c3RlbS5vdXQucHJpbnRsbigiSzIgaGFuZGxpbmcgVCIpOyByZXR1cm4gdDsgfQp9CmNsYXNzIEszQSBpbXBsZW1lbnRzIEsgewogICAgcHVibGljIDxUPlQgaGFuZGxlKFQgdCkgeyB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW4gb25seSBoYW5kbGUgQSIpOyB9CiAgICBwdWJsaWMgQSBoYW5kbGUoQSBhKSB7IFN5c3RlbS5vdXQucHJpbnRsbigiSzMgaGFuZGxpbmcgQSIpOyByZXR1cm4gYTsgfQp9CmNsYXNzIEszQiBpbXBsZW1lbnRzIEsgewogICAgcHVibGljIDxUPlQgaGFuZGxlKFQgdCkgeyB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDYW4gb25seSBoYW5kbGUgQiIpOyB9CiAgICBwdWJsaWMgQiBoYW5kbGUoQiBiKSB7IFN5c3RlbS5vdXQucHJpbnRsbigiSzMgaGFuZGxpbmcgQiIpOyByZXR1cm4gYjsgfQp9Cg==