Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[Java1.8] UnaryOperatorの結合関数の勉強

More than 5 years have passed since last update.

UnaryOperatorのお勉強です。

UnaryOperatorとUnaryOperatorを結合した関数はどのようにかけるだろうか?

いろいろやってみる

public interface UnaryOperatorConnector<T> extends UnaryOperator<T>{
    public UnaryOperator<T> apply( UnaryOperator<T> t);
}

こうかな・・・

public class UnaryOperatorConnectorTest{
    @Test
    public void test(){
        UnaryOperatorConnector<String> o2 = s -> s + "a";
}

あれ???うーん・・・・・

あ、composeね。

public class UnaryOperatorConnectorTest{
    @Test
    public void test(){
        UnarryOperator<String> o1 = s -> s+"*";
        UnaryOperatorConnector<String> o2 = o1.compose( s -> s+ "*" );
}

あれ???うーん・・・・・

UnaryOperator<String> op1 = s -> s + "*";
UnaryOperator<String> op2 = s -> s + "+";
Function<String,String> uo = op2.andThen(op1);

OKだ・・・

UnaryOperator<String> op1 = s -> s + "*";
Function<String,String> uo2 = op2.andThen(s -> s+"*");

OKだ・・・
つまり、UnaryOperator.composeがFunctionを返してしまうのがおかしいんですかね。

結論

つまり、一旦Functionで受け取ってUnaryOperatorに変換しなければならないらしい。

UnaryOperators.java
public class UnaryOperators<T> implements UnaryOperator<T> {
    private Function<T,T>[] operators;

    public UnaryOperators(UnaryOperator<T>... operators){
        this.operators = operators;
    }
   @Override
    public T apply(T t) {
        return Arrays.asList(operators).stream().reduce (Function::compose ).get().apply(t) ;
    }
    public static <T> UnaryOperator<T> connect(UnaryOperator<T>... ops){
        return x -> Arrays.<Function<T,T>>asList(ops).stream().reduce( Function::compose ).get().apply(x);
    }
}
public class UnaryOperatorsTest{
   @Test
    public void test2(){
        UnaryOperator<String> op1 = s -> s + "*";
        UnaryOperator<String> op2 = s -> s + "+";

        UnaryOperator<String> op3 = new UnaryOperators<>(op1,op2);
        UnaryOperator<String> op4 = UnaryOperators.connect(op1,op2);

        System.out.println(op3.apply("xxx"));
        System.out.println(op4.apply("yyy"));
    }
}

実行結果

xxx+*
yyy+*

関数をデータのように扱い始めると、頭が沸騰しそうです。

こういうことをやっていると、「関数もオブジェクトなんだな」という事を実感します。
むしろ関数型言語側からいえば、「オブジェクトもまた関数なんだよ」と言う事かもしれませんが。

というか

    public static <T> UnaryOperator<T> connect(UnaryOperator<T>... ops){
        return Arrays.<Function<T,T>>asList(ops).stream().reduce( Function::compose ).get()::apply;
    }

こっちのほうがいいか。
クールな書き方があれば教えてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away