0

Google Guava に入ったばかりで、強力なツールのように思えます。Predicates を使用して特定のプロパティでフィルター処理する方法がわかります。私の質問で述語を連鎖させる方法FluentIterableは、単一のプロパティをフィルタリングする最良の方法です。

たとえば、車のコレクションがあるとします。Cars.getPaintColor() をフィルタリングして、黒、赤、および黄色の車を取得するにはどうすればよいですか? 3 つの別個の述語を作成して FluentIterable を使用するのは、扱いにくいようです。特に私の使用では、同じプロパティに 10 個以上のフィルターが必要になる可能性があり、10 個の述語を作成したくありません。

ありがとうございます!

        List<String> colorList = (List<String>)filterCriteria.get("Color");
        List<String> makeList = (List<String>)filterCriteria.get("Make");
        List<String> rimSizeList = (List<String>)filterCriteria.get("RimSize");

        Predicate<String> predColor = Predicates.in(ImmutableSet.copyOf(colorList));
        Predicate<CarObj> predDirection2 = Predicates.compose(predColor ,[????] );

        Predicate<String> predMakeList  = Predicates.in(ImmutableSet.copyOf(makeList));
        Predicate<CarObj> predMakeList2 = Predicates.compose(predMakeList, [????] );

        Predicate<String> predRimSize = Predicates.in(ImmutableSet.copyOf(rimSizeList));
        Predicate<CarObj> predRimSize2 = Predicates.compose(predRimSize, [????] );

        Collection<CarObj> filtered = FluentIterable.from(mAllCars)
                .filter(predDirection2)
                .filter(predMakeList2)
                .filter(predRimSize2)
                .toList();

リストを使用しているため、ImmutableSet を作成するときcopyOfに代わりに使用しました。of

構成の 2 番目のパラメーターに何を入力すればよいかわかりません。私はそれがこのようなものだと推測しています... CarObj クラスで。

static Predicate<CarObj> byColor= new Predicate<CarObj>() {
    public boolean apply(CarObj input) {

        // What do I put here?
    }
};
4

2 に答える 2

3

したがって、ペイントの色が黒、赤、黄色のいずれでPredicateあるかを確認するには、セットにその色が含まれているかどうかを確認するを作成します。

Predicate<PaintColor> p = Predicates.in(ImmutableSet.of(
    PaintColor.RED, PaintColor.BLACK, PaintColor.YELLOW));

Function<Car, PaintColor>次に、クラスのペイント カラー プロパティを返すでそれを構成できます。

Predicate<Car> p2 = Predicates.compose(p, Car.GET_PAINT_COLOR_FUNCTION);

編集:

Car.GET_PAINT_COLOR_FUNCTIONつまり、次のようなことを意味します。

public static final Function<Car, PaintColor> GET_PAINT_COLOR_FUNCTION =
    new Function<Car, PaintColor>() {
      @Override public PaintColor apply(Car car) {
        return car.getPaintColor();
      }
    });

コメントで述べたように、必要に応じて実際の型に適応させることができます。たとえば、Function<CarObj, String>代わりに a にします。

于 2015-01-09T02:01:07.947 に答える
2

ColinD によって提案されているように、抽出Function<Car, PaintColor>を a で構成する代わりに、パラメーター化された を記述します。Predicates.in()Predicate<Car>

public class CarPaintColorPredicate implements Predicate<Car> {
    private final PaintColor paintColor;

    public CarPaintColorPredicate(PaintColor paintColor) {
        this.paintColor = paintColor;
    }

    @Override
    public boolean apply(@Nullable Car input) {
        return input != null && input.getPaintColor() == paintColor;
    }
}

その後、直接使用できます:

FluentIterable.from(cars)
        .filter(new CarPaintColorPredicate(PaintColor.RED))
        .toList();

または複数の色を組み合わせる:

FluentIterable.from(cars)
        .filter(Predicates.or(
            new CarPaintColorPredicate(PaintColor.RED),
            new CarPaintColorPredicate(PaintColor.BLACK)))
        .toList();

または、他のタイプの述語と組み合わせることもできます。

FluentIterable.from(cars)
        .filter(new CarPaintColorPredicate(PaintColor.RED))
        .filter(new CarMakePredicate("Ferrari"))
        .toList();

完全にするために、 を含むバージョンFunction<Car, PaintColor>は次のとおりです。

public enum CarPaintColorFunction implements Function<Car, PaintColor> {
    INSTANCE;

    @Override
    public PaintColor apply(@Nullable Car input) {
        return input == null ? null : input.getPaintColor();
    }
}

Function単純にプロパティの値を返します。この値は、コンポジションSetを通じて受け入れられた値のコレクション (できれば a )と比較されます。Predicate

FluentIterable.from(cars)
        .filter(Predicates.compose(
            Predicates.in(Sets.immutableEnumSet(PaintColor.RED, PaintColor.BLACK)),
            CarPaintColorFunction.INSTANCE))
        .toList();

Guava WikiのFunctional Explainedページで実際に説明されていることはすべてです。

于 2015-01-09T16:14:03.833 に答える