2017-04-06 8 views
0

私のクラスには重複したコードがたくさんあるいくつかのメソッドが含まれているという問題が発生しました。この背後にある理由は、各メソッドがエントリのリストを横断し、特定のエントリメソッドを呼び出すためです。コードでJava Lambdas:パラメータとしてのメソッド名の送信

...

LowLevelClassクラスには、次の構造を有する:

public class LowLevelClass { 

    // constructor omitted 

    public boolean doSomethingA() { 
     // some non-duplicated code 
     return true; 
    } 

    public boolean doSomethingB() { 
     // some non-duplicated code 
     return true; 
    } 

    public boolean doSomethingC() { 
     // some non-duplicated code 
     return true; 
    } 
} 

トップレベルのクラスはLow​​LevelClassesのリストが含まれているとメソッドの同じ数が、この時間を持っている、と重複がたくさん:

public class HighLevelClass { 

    private List<LowLevelClass> classes = new ArrayList<>(); 

    public HighLevelClass() { 
     this.classes.add(new LowLevelClass(/* params */)); 
     this.classes.add(new LowLevelClass(/* params */)); 
     this.classes.add(new LowLevelClass(/* params */)); 
    } 

    public void doA() { 
     System.out.println("Doing ..."); 
     for (LowLevelClass entry : classes) { 
      System.out.println("Doing something..."); 
      entry.doSomethingA(); 
      System.out.println("Done"); 
     } 
    } 

    public void doB() { 
     System.out.println("Doing ..."); 
     for (LowLevelClass entry : classes) { 
      System.out.println("Doing something..."); 
      entry.doSomethingB(); 
      System.out.println("Done"); 
     } 
    } 

    public void doC() { 
     System.out.println("Doing ..."); 
     for (LowLevelClass entry : classes) { 
      System.out.println("Doing something..."); 
      entry.doSomethingC(); 
      System.out.println("Done"); 
     } 
    } 
} 

私の目標は、の形で何かを持っていることです

public class HighLevelClass { 

    private List<LowLevelClass> classes = new ArrayList<>(); 

    public HighLevelClass() { 
     this.classes.add(new LowLevelClass()); 
     this.classes.add(new LowLevelClass()); 
     this.classes.add(new LowLevelClass()); 
    } 

    public void doSomething(Lambda /* Functional interface*/ operation) { 
     System.out.println("Doing A"); 
     for (LowLevelClass entry : classes) { 
      System.out.println("Doing something..."); 
      entry.operation; // or something else... 
      System.out.println("Done"); 
     } 
    } 

    public void doSomethingA() { 
     // my goal... and maybe in totally wrong direction is to send something in form of... 
     return doSomething(LowLevelClass::doSomethingA); 
    } 

    // etc 
} 

これはJava 8 Lambdasで実行できますか?つまり、指定したリストの各エントリに対して実行するメソッドを定義できますか? ジョーンVerneeジョフリーによって提供さ

EDIT 1つの

答えは正しいです!

最終的には、解決策はプレディケートを使用することでした。

EDIT 2

私の最初の方法で

パブリッククラスHighLevelClass {

private List<LowLevelClass> classes = new ArrayList<>(); 

public HighLevelClass() { 
    this.classes.add(new LowLevelClass()); 
    this.classes.add(new LowLevelClass()); 
    this.classes.add(new LowLevelClass()); 
} 

public boolean doSomething(Predicate<LowLevelClass> function) { 
    System.out.println("Doing A"); 
    for (LowLevelClass entry : classes) { 
     System.out.println("Doing something..."); 
     boolean val = function.test(entry); 
     System.out.println("Done " + val); 
    } 
    return someEndVerdict; 
} 

public boolean doSomethingA() { 
    return doSomething(LowLevelClass::doSomethingA); 
} 

// etc 

を}(私は最終的に消費者を使用しなかった理由... EDIT 2を参照してください) HighLevelClassにbooleanの戻り値の型が含まれていませんでした。それは、私は消費者にcontastとして述語(述語を使用した理由だ私をもっとよく合っブール値を返します - そしてその私が最初に言及するのを忘れてしまった:ヘルプと時間のための((()

おかげ

+0

(list.stream 'など)のforEach()'。? – Kayaman

+0

なぜラムダでなければならないのですか?どのような関数ポインタを渡すことができないのですか? –

+2

なぜですか?あなたは適切な機能的なインターフェイスタイプを試しましたか? 'Comsumer 'のように? –

答えて

2

!あなたはコールまたはラムダを伴い、そしてあなたが右引数の型を見つける必要の方法を、書くの方法ではないかもしれ方法、道を混同してはならない。

あなたがメソッドを記述する場合、引数の型に焦点を当てる必要があります。関数の1つが関数を表すオブジェクトであれば、必要なのはundこの関数が一致する適切なシグネチャを消してください。これは、あなたがあなたのparamの型として置くべき機能的なインタフェースを提供します。

あなたの場合、タイプLowLevelClassの1つの引数をとり、値を返さない関数が必要です。あなたはそれに驚かれるかもしれませんが、静的メソッドではなく、クラスのインスタンス(this)を最初の引数として取る関数としてインスタンスメソッドを考える必要があります。

したがって、Consumer<LowLevelClass>インタフェースが何をしたいです:

public void doSomething(Consumer<LowLevelClass> operation) { 
    System.out.println("Doing A"); 
    for (LowLevelClass entry : classes) { 
     System.out.println("Doing something..."); 
     operation.accept(entry); // or something else... 
     System.out.println("Done"); 
    } 
} 

public void doSomethingA() { 
    return doSomething(LowLevelClass::doSomethingA); 
} 
+0

これは正解です。また、戻り値を置くのを忘れてしまった。これは最終的に私をConsumerの代わりにPredicatedに導いた。いずれにせよ、その説明は現場で行われている。 – xanmcgregor

関連する問題