web-dev-qa-db-ja.com

Javaの述語

JavaでPredicateを使用するコードを調べています。 Predicateを使用したことがありません。誰かがPredicateとそのJavaでの実装のチュートリアルや概念説明に私を導くことができますか?

97
srikanth

グアバから com.google.common.base.Predicate<T> について話していると思います。

APIから:

指定された入力のtrueまたはfalse値を決定します。たとえば、RegexPredicatePredicate<String>を実装し、指定された正規表現に一致するすべての文字列に対してtrueを返します。

これは基本的に、booleanテストのOOP抽象化です。

たとえば、次のようなヘルパーメソッドがあります。

static boolean isEven(int num) {
   return (num % 2) == 0; // simple
}

これで、List<Integer>を指定すると、次のような偶数のみを処理できます。

    List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    for (int number : numbers) {
        if (isEven(number)) {
            process(number);
        }
    }

Predicateを使用すると、ifテストは型として抽象化されます。これにより、 Iterables などのAPIの残りの部分と相互運用できます。これには、Predicateを受け取る多くのユーティリティメソッドがあります。

したがって、次のように記述できます。

    Predicate<Integer> isEven = new Predicate<Integer>() {
        @Override public boolean apply(Integer number) {
            return (number % 2) == 0;
        }               
    };
    Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);

    for (int number : evenNumbers) {
        process(number);
    }

これで、for-eachループはifテストなしではるかに簡単になったことに注意してください。 filterを使用してPredicate- ingでIterable<Integer> evenNumbersを定義することにより、より高いレベルの抽象化に到達しました。

APIリンク


高階関数について

Predicateを使用すると、Iterables.filterを高階関数と呼ばれるものとして使用できます。これには、単独で多くの利点があります。上記のList<Integer> numbersの例をご覧ください。すべての数値が正であるかどうかをテストするとします。このようなものを書くことができます:

static boolean isAllPositive(Iterable<Integer> numbers) {
    for (Integer number : numbers) {
        if (number < 0) {
            return false;
        }
    }
    return true;
}

//...
if (isAllPositive(numbers)) {
    System.out.println("Yep!");
}

Predicateを使用して、残りのライブラリと相互運用する場合、代わりに次のように記述できます。

Predicate<Integer> isPositive = new Predicate<Integer>() {
    @Override public boolean apply(Integer number) {
        return number > 0;
    }       
};

//...
if (Iterables.all(numbers, isPositive)) {
    System.out.println("Yep!");
}

「すべての要素を指定された述語でフィルタリングする」、「すべての要素が指定された述語を満たしているかどうかを確認する」などのルーチンのより高い抽象化で値を確認できるようになりました。

残念ながらJavaにはファーストクラスのメソッドがありません。methodsIterables.filterおよびIterables.allに渡すことはできません。もちろん、Javaでobjectsを渡すことができます。したがって、Predicateタイプが定義され、代わりにこのインターフェースを実装するobjectsを渡します。

こちらもご覧ください

201

述語は、真/偽(つまりブール値)である命題とは対照的に、真/偽(つまりブール値)を返す関数です。 Javaでは、スタンドアロン関数を使用できないため、述語を表すオブジェクトのインターフェイスを作成して述語を作成し、そのインターフェイスを実装するクラスを提供します。述部のインターフェースの例は次のとおりです。

public interface Predicate<ARGTYPE>
{
    public boolean evaluate(ARGTYPE arg);
}

そして、次のような実装があるかもしれません。

public class Tautology<E> implements Predicate<E>
{
     public boolean evaluate(E arg){
         return true;
     }
}

概念的な理解を深めるために、1次論理について読むことをお勧めします。

編集
標準 Predicate インターフェース( Java.util.function.Predicate )Java APIのJavaで定義されています8. Java 8より前では、 com.google.common.base.Predicate インターフェース Guava

また、Java 8では、ラムダを使用して述語を記述する方がはるかに簡単であることに注意してください。たとえば、Java 8以降では、上記のような名前付きのTautologyサブクラスを定義する代わりに、p -> trueを関数に渡すことができます。

14

Java doc の例またはPredicateの使用例 here を表示できます。

基本的に、特定の基準に基づいて結果セット内の行をフィルタリングし、基準を満たす行に対してtrueを返すために使用されます。

 // the age column to be between 7 and 10
    AgeFilter filter = new AgeFilter(7, 10, 3);

    // set the filter.
    resultset.beforeFirst();
    resultset.setFilter(filter);
0
techzen

Micheal が言ったことに加えて:

Javaでのコレクションのフィルタリングでは、次のようにPredicateを使用できます。

public static <T> Collection<T> filter(final Collection<T> target,
   final Predicate<T> predicate) {
  final Collection<T> result = new ArrayList<T>();
  for (final T element : target) {
   if (predicate.apply(element)) {
    result.add(element);
   }
  }
  return result;
}

可能な述語の1つは次のとおりです。

final Predicate<DisplayFieldDto> filterCriteria = 
                    new Predicate<DisplayFieldDto>() {
   public boolean apply(final DisplayFieldDto displayFieldDto) {
    return displayFieldDto.isDisplay();
   }
  };

使用法:

 final List<DisplayFieldDto> filteredList=
 (List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
0
jai