/* 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
K1 k1 = new K1();
K2 k2 = new K2();
K3 k3 = new K3();
// construct A chain
Function<A, A> handleA = wrap(k3::handle);
handleA = handleA.compose(wrap(k2::handle));
handleA = handleA.compose(wrap(k1::handle));
// try with A
A sampleA = new A();
handleA.apply(sampleA);
// construct B chain
Function<B,B> handleB = wrap(k3::handle);
handleB = handleB.compose(wrap(k2::handle));
handleB = handleB.compose(wrap(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
}
private static <T>Function<T,T> wrap(Consumer<T> consumer) {
return t -> { consumer.accept(t); return t; };
}
}
interface S {}
class A implements S {}
class B implements S {}
class K1 {
public void handle
(S s
) { System.
out.
println("K1 handling S"); } }
class K2 {
public void handle
(S s
) { System.
out.
println("K2 handling S"); } }
class K3 {
public void handle
(A a
) { System.
out.
println("K3 handling A"); } public void handle
(B b
) { System.
out.
println("K3 handling B"); } }
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLio7CmltcG9ydCBqYXZhLmxhbmcuKjsKaW1wb3J0IGphdmEuaW8uKjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CiAgICAgICAgLy8gdXNlZCBpbiBib3RoIGNoYWlucwogICAgICAgIEsxIGsxID0gbmV3IEsxKCk7CiAgICAgICAgSzIgazIgPSBuZXcgSzIoKTsKICAgICAgICBLMyBrMyA9IG5ldyBLMygpOwogICAgICAgIC8vIGNvbnN0cnVjdCBBIGNoYWluCiAgICAgICAgRnVuY3Rpb248QSwgQT4gaGFuZGxlQSA9IHdyYXAoazM6OmhhbmRsZSk7CiAgICAgICAgaGFuZGxlQSA9IGhhbmRsZUEuY29tcG9zZSh3cmFwKGsyOjpoYW5kbGUpKTsKICAgICAgICBoYW5kbGVBID0gaGFuZGxlQS5jb21wb3NlKHdyYXAoazE6OmhhbmRsZSkpOwogICAgICAgIC8vIHRyeSB3aXRoIEEKICAgICAgICBBIHNhbXBsZUEgPSBuZXcgQSgpOwogICAgICAgIGhhbmRsZUEuYXBwbHkoc2FtcGxlQSk7CiAgICAgICAgLy8gY29uc3RydWN0IEIgY2hhaW4KICAgICAgICBGdW5jdGlvbjxCLEI+IGhhbmRsZUIgPSB3cmFwKGszOjpoYW5kbGUpOwogICAgICAgIGhhbmRsZUIgPSBoYW5kbGVCLmNvbXBvc2Uod3JhcChrMjo6aGFuZGxlKSk7CiAgICAgICAgaGFuZGxlQiA9IGhhbmRsZUIuY29tcG9zZSh3cmFwKGsxOjpoYW5kbGUpKTsKICAgICAgICAvLyB0cnkgd2l0aCBCCiAgICAgICAgQiBzYW1wbGVCID0gbmV3IEIoKTsKICAgICAgICBCIHJlc3VsdCA9IGhhbmRsZUIuYXBwbHkoc2FtcGxlQik7IC8vIHlvdSBjYW4gZXZlbiBnZXQgYSBCIHJlc3VsdCBmcm9tIHRoZSB3aG9sZSBjaGFpbgoJfQogICAgcHJpdmF0ZSBzdGF0aWMgPFQ+RnVuY3Rpb248VCxUPiB3cmFwKENvbnN1bWVyPFQ+IGNvbnN1bWVyKSB7CiAgICAgICAgcmV0dXJuIHQgLT4geyBjb25zdW1lci5hY2NlcHQodCk7IHJldHVybiB0OyB9OwogICAgfQp9CgppbnRlcmZhY2UgUyB7fQpjbGFzcyBBIGltcGxlbWVudHMgUyB7fQpjbGFzcyBCIGltcGxlbWVudHMgUyB7fQoKY2xhc3MgSzEgewogICAgcHVibGljIHZvaWQgaGFuZGxlKFMgcykgeyBTeXN0ZW0ub3V0LnByaW50bG4oIksxIGhhbmRsaW5nIFMiKTsgfQp9CgpjbGFzcyBLMiB7CiAgICBwdWJsaWMgdm9pZCBoYW5kbGUoUyBzKSB7IFN5c3RlbS5vdXQucHJpbnRsbigiSzIgaGFuZGxpbmcgUyIpOyB9Cn0KY2xhc3MgSzMgewogICAgcHVibGljIHZvaWQgaGFuZGxlKEEgYSkgeyBTeXN0ZW0ub3V0LnByaW50bG4oIkszIGhhbmRsaW5nIEEiKTsgfQogICAgcHVibGljIHZvaWQgaGFuZGxlKEIgYikgeyBTeXN0ZW0ub3V0LnByaW50bG4oIkszIGhhbmRsaW5nIEIiKTsgfQp9Cg==