Google Guava - 过滤单个属性的多个输入
Google Guava - Filter Multiple Inputs on Single Property
我刚刚接触 Google Guava,它似乎是一个强大的工具,我看到了如何使用谓词并按特定属性进行过滤。如何在 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
。
我不确定在撰写的第二个参数中放什么。我猜它是这样的......在 CarObj class.
static Predicate<CarObj> byColor= new Predicate<CarObj>() {
public boolean apply(CarObj input) {
// What do I put here?
}
};
因此,要检查油漆颜色是黑色、红色还是黄色之一,您需要创建一个 Predicate
来检查一组是否包含该颜色:
Predicate<PaintColor> p = Predicates.in(ImmutableSet.of(
PaintColor.RED, PaintColor.BLACK, PaintColor.YELLOW));
然后您可以将 Function<Car, PaintColor>
与 returns 油漆颜色 属性 class:
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>
。
按照 ColinD 的建议,用 Predicates.in()
组合提取 Function<Car, PaintColor>
的替代方法是编写参数化的 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
只是 returns 属性 的值,然后通过 Predicate
组成:
FluentIterable.from(cars)
.filter(Predicates.compose(
Predicates.in(Sets.immutableEnumSet(PaintColor.RED, PaintColor.BLACK)),
CarPaintColorFunction.INSTANCE))
.toList();
所有这些都在 Guava Wiki 的 Functional Explained 页面中得到了真正的解释。
我刚刚接触 Google Guava,它似乎是一个强大的工具,我看到了如何使用谓词并按特定属性进行过滤。如何在 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
。
我不确定在撰写的第二个参数中放什么。我猜它是这样的......在 CarObj class.
static Predicate<CarObj> byColor= new Predicate<CarObj>() {
public boolean apply(CarObj input) {
// What do I put here?
}
};
因此,要检查油漆颜色是黑色、红色还是黄色之一,您需要创建一个 Predicate
来检查一组是否包含该颜色:
Predicate<PaintColor> p = Predicates.in(ImmutableSet.of(
PaintColor.RED, PaintColor.BLACK, PaintColor.YELLOW));
然后您可以将 Function<Car, PaintColor>
与 returns 油漆颜色 属性 class:
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>
。
按照 ColinD 的建议,用 Predicates.in()
组合提取 Function<Car, PaintColor>
的替代方法是编写参数化的 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
只是 returns 属性 的值,然后通过 Predicate
组成:
FluentIterable.from(cars)
.filter(Predicates.compose(
Predicates.in(Sets.immutableEnumSet(PaintColor.RED, PaintColor.BLACK)),
CarPaintColorFunction.INSTANCE))
.toList();
所有这些都在 Guava Wiki 的 Functional Explained 页面中得到了真正的解释。