0

I just got into Google Guava and it seems like a powerful tool and I see how you can use Predicates and filter by a specific property. How you can also chain predicates in FluentIterable My question is what's the best way to filter for a single property.

For example, if I have a collection of Cars. How do I filter the Cars.getPaintColor() to give me cars that are in Black, Red, and Yellow? Creating 3 separate predicates and using FluentIterable seems clumsy. Especially in my use, I could want possibly 10+ filters on the same property and I wouldn't want to create 10 Predicates.

Thanks you!

        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();

Since I am using an List, I used copyOf instead of of when creating ImmutableSet.

I am not sure what to put in the second parameter of the compose. I am guessing it is something like this... in the CarObj class.

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>返回类的油漆颜色属性的 a 来组合它:

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>改为改为。

于 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的集合(希望是 a )进行比较:SetPredicate

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

所有这些都在 Guava Wiki的功能解释页面中得到了真正的解释。

于 2015-01-09T16:14:03.833 回答