2

I am trying to implement a pipeline design pattern using Java 8 with the below article for my reference:

https://stackoverflow.com/a/58713936/4770397

Code:

public abstract class Pipeline{
Function<Integer, Integer> addOne = it -> {
        System.out.println(it + 1);
        return it + 1;
    };

Function<Integer, Integer> addTwo = it -> {
        System.out.println(it + 2);
        return it + 2;
    };

Function<Integer, Integer> timesTwo = input -> {
        System.out.println(input * 2);
        return input * 2;
    };

final Function<Integer, Integer> pipe = sourceInt
    .andThen(timesTwo)
    .andThen(addOne)
    .andThen(addTwo);
}

I am trying to add one abstract method & want to override it.
I am trying to do something like:

abstract BiFunction<Integer, Integer,Integer> overriden; 

and change pipe to:

final Function<Integer, Integer> pipe = sourceInt
    .andThen(timesTwo)
    .andThen(overriden)
    .andThen(addOne)
    .andThen(addTwo);
}

But the problem is, I don't know to declare a Function<Integer, Integer> as an abstract method.

mayank bisht
  • 618
  • 3
  • 14
  • 43

2 Answers2

3

You can just declare a regular abstract method that takes an Integer and returns an Integer and use the method reference syntax to refer to it:

public abstract Integer overridden(Integer input);

final Function<Integer, Integer> pipe = sourceInt
    .andThen(timesTwo)
    .andThen(this::overridden)
    .andThen(addOne)
    .andThen(addTwo);
Naman
  • 27,789
  • 26
  • 218
  • 353
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thanks for the answer, instead of 1 parameter how can I pass 2 parameters? – mayank bisht Mar 29 '20 at 17:31
  • @mayankbisht Are you looking for [`BiFunction`](https://docs.oracle.com/javase/8/docs/api/java/util/function/BiFunction.html)? – Sweeper Mar 29 '20 at 17:32
  • @Sweeper- yes I am looking for BiFunction. – mayank bisht Mar 29 '20 at 17:35
  • 1
    @mayankbisht all the time, when you wrote lines similar to `Function timesTwo = input -> {...};`, that signified accepting one parameter and the question never mentioned anything about passing 2 parameters. Do make an edit for what you intend to ask or else the questions are merely lost. – Naman Mar 30 '20 at 04:59
  • @Naman - Thank you for the suggestion. I have updated the question. – mayank bisht Mar 30 '20 at 05:11
  • Hope @Sweeper would update the answer soon as well. But the concept as highlighted currently could very well remain the same. – Naman Mar 30 '20 at 05:12
  • @mayankbisht You see, now the pipeline you wrote doesn't really make sense. `sourceInt.andThen(timesTwo)` is a `Function`, so it will produce _one_ integer as its output. You are trying to somehow connect that to a function that accepts _two_ inputs. Do you see the problem here? Where should the other parameter for `overridden` come from? – Sweeper Mar 30 '20 at 07:53
1

Fields aren't a subject to polymorphism - you need a method. You either write

  1. a method that just returns a Function<Integer, Integer> instance

    public abstract Function<Integer, Integer> getMyFunction();
    
  2. a method that actually represents a Function<Integer, Integer>

    public abstract Integer myFunction(Integer i);
    

and then do

.andThen(getMyFunction())

or

.andThen(i -> myFunction(i))
// .andThen(this::myFunction) // fancier

respectively.

For example,

interface I {
  Function<Integer, Integer> getFunction();
  Integer function(Integer i);
}

class A implements I {
  @Override
  public Function<Integer, Integer> getFunction() {
    return i -> i + 1;
  }

  @Override
  public Integer function(Integer i) {
    return i + 1;
  }
}

class B implements I {
  @Override
  public Function<Integer, Integer> getFunction() {
    return i -> i * 2;
  }

  @Override
  public Integer function(Integer i) {
    return i * 2;
  }
}

class T {
  public static void main(String[] args) {
    A a = new A();
    B b = new B();

    Function<Integer, Integer> f1 = a.getFunction().andThen(b.getFunction());
    System.out.println(f1.apply(2)); // 6

    Function<Integer, Integer> f2 = a.getFunction().andThen(b::function);
    System.out.println(f2.apply(2)); // 6

    Function<Integer, Integer> f3 = ((Function<Integer, Integer>)a::function).andThen(b::function);
    System.out.println(f3.apply(2)); // 6
  }
}
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142