Java 如何通过一个由布尔变量定义的3种过滤器类型的ArrayList进行过滤?
我有主要的Java 如何通过一个由布尔变量定义的3种过滤器类型的ArrayList进行过滤?,java,arraylist,Java,Arraylist,我有主要的arraylistcars,我试图用三种不同的方式对其进行过滤。每个过滤器可以单独使用,也可以一起使用 因此,如果有三个过滤器:x、y和z,并且只有x和y为真,那么一个新的数组列表将考虑过滤器x和y,并且将显示每个条目。如果x、y和z均为真,则主数组列表“cars”将通过所有三种方法进行过滤,并将创建一个新的数组列表,然后显示所有过滤后剩下的内容 我有每个过滤器的布尔实例变量,每当调用特定过滤器的方法时,这些变量都设置为true。例如,如果我要过滤cars数组列表以查看汽车是否为电动汽
arraylistcars
,我试图用三种不同的方式对其进行过滤。每个过滤器可以单独使用,也可以一起使用
因此,如果有三个过滤器:x、y和z,并且只有x和y为真,那么一个新的数组列表将考虑过滤器x和y,并且将显示每个条目。如果x、y和z均为真,则主数组列表“cars”将通过所有三种方法进行过滤,并将创建一个新的数组列表,然后显示所有过滤后剩下的内容
我有每个过滤器的布尔实例变量,每当调用特定过滤器的方法时,这些变量都设置为true。例如,如果我要过滤cars
数组列表以查看汽车是否为电动汽车,我会在public void filterByElectric()方法的开头设置filterElectric=true
,然后在使用for循环的地方添加代码,以检查数组列表的每个索引位置中的每个Car
对象是否是电动的
我知道我可以简单地做一个大的if语句,它允许我说if(filterElectric==true)
,然后显示带有过滤汽车的新数组列表,我知道我可以使用&&
一次使用多个过滤器(如果它们为true)只需将新创建的数组列表附加在一起,并用for循环显示每个新筛选的条目,但这样做意味着我必须为所有场景设置条件
我怎样才能首先检查三个过滤器中的哪些是真的,然后在我知道哪些过滤器变量设置为真后,我可以将这两个过滤列表附加在一起以显示
公共的一切{
如果(filX==true&&filY==true&&filZ==true){
//附加所有筛选的列表,然后打印新创建的列表
//列表到系统
过滤。添加全部(filX);
过滤。添加全部(filY);
过滤。添加全部(filZ);
用于(车辆a:已过滤){
System.out.println(a.disp());
}
}else if(filX==true&&filY==true&filZ==false){
过滤。添加全部(filX);
过滤。添加全部(filY);
用于(车辆a:已过滤){
System.out.println(a.disp());
}
//然后它继续前进。。。。
//有没有更快的方法
//而不是用&&写所有条件?
}
}
公共无效筛选器x(){
filX=真;
用于(汽车a:汽车){
如果(a.getWhather()==1){
xList.添加(a);
}否则{
打破
}
}
}
公共空滤器(){
费里=真;
用于(汽车a:汽车){
如果(a.getSomething()==true){
添加(a);
}否则{
打破
}
}
}
公共无效filZ(双a,双b){
filZ=真;
用于(汽车a:汽车){
如果(a.getP()>=a&&a.getP()快速解决方案,这可能就是您要寻找的
从汽车开始:
package so.car;
public class Car {
private String name;
private boolean electric;
private boolean awd;
private boolean automatic;
public Car(String name, boolean electric, boolean awd, boolean automatic) {
this.name = name;
this.electric = electric;
this.awd = awd;
this.automatic = automatic;
}
public boolean isElectric() {
return electric;
}
public void setElectric(boolean electric) {
this.electric = electric;
}
public boolean isAwd() {
return awd;
}
public void setAwd(boolean awd) {
this.awd = awd;
}
public boolean isAutomatic() {
return automatic;
}
public void setAutomatic(boolean automatic) {
this.automatic = automatic;
}
@Override
public String toString() {
return "Car [name=" + name + "]";
}
}
然后,需要处理同时运行多个过滤器的问题:
package so.car;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
public class CarFilters {
private Map<String, Function<Car, Boolean>> filters;
public CarFilters(Map<String, Function<Car, Boolean>> filters) {
this.filters = filters;
}
public List<String> getPassingFilterNames(Car car) {
List<String> passingFilterNames = new ArrayList<>();
for (Entry<String, Function<Car, Boolean>> entry : filters.entrySet()) {
String filterName = entry.getKey();
Function<Car, Boolean> predicateFunction = entry.getValue();
if (predicateFunction.apply(car)) {
passingFilterNames.add(filterName);
}
}
return passingFilterNames;
}
}
您可以基于要应用的过滤逻辑构建谓词,并仅使用此谓词过滤流:
public Predicate<Car> filter = car -> {
boolean filter = true;
if (isfilterEletricOn()) {
filter = filter && car.isEletric();
}
if (isfilterOffRoadOn()) {
filter = filter && car.isOffRoad();
}
if (isfilterSportOn()) {
filter = filter && car.isSport();
}
return filter;
};
cars.stream().filter(filter).collect(Collectors.toList());
公共谓词过滤器=car->{
布尔过滤器=真;
if(isFilterRetricon()){
filter=filter&car.isEletric();
}
如果(isfilterOffRoadOn()){
过滤器=过滤器&car.isofroad();
}
if(isfilterSportOn()){
filter=filter&car.isSport();
}
回流过滤器;
};
cars.stream().filter(filter.collect(collector.toList());
您可以执行以下操作:
public static Predicate<Car> filteringAll(boolean filterToyota, boolean filterAudi) {
return p -> (p.getManufacturer().getName().equals("Toyota") && filterToyota) || (p.getManufacturer().getName().equals("Audi") && filterAudi);
}
List<Car> listOfFilteredCars = listOfCars.stream().filter(filteringAll(false, true)).collect(Collectors.toList());
制造商类别
如果希望代码尽可能短,可以这样做:
public static List<Car> filter(
List<Car> allCars,
boolean onlyElectric,
boolean onlyAllWheelsDrive,
boolean onlyAutomatic)
{
return allCars.stream()
.filter((Car car) -> !onlyElectric || car.isElectric())
.filter((Car car) -> !onlyAllWheelsDrive|| car.isAllWheelsDrive())
.filter((Car car) -> !onlyAutomatic|| car.isAutomatic())
.collect(Collectors.toList());
}
filter(allCars, CarFilter.Electric, CarFilter.Automatic);
这可以更容易地翻译成人类可以理解的语言:如果选择了“onlyElectric”过滤器,检查汽车是否真的是电动的。如果没有选择,只需返回true,这意味着过滤器接受每辆汽车
在您编写这段代码的时候,它将是有意义的。几天后,当您回来添加另一个过滤器时,您可能会问自己:3个布尔参数中的哪一个是哪一个,为什么它们的顺序正好如此?另一种解决方案是使用enum
而不是这些布尔值
public enum CarFilter {
Electric, AllWheelsDrive, Automatic
}
public static List<Car> filter(
List<Car> allCars,
CarFilter... filters)
{
EnumSet<CarFilter> set = EnumSet.noneOf(CarFilter.class);
Collections.addAll(set, filters);
return allCars.stream()
.filter((Car car) -> !set.contains(CarFilter.Electric) || car.isElectric())
.filter((Car car) -> !set.contains(CarFilter.AllWheelsDrive) || car.isAllWheelsDrive())
.filter((Car car) -> !set.contains(CarFilter.Automatic) || car.isAutomatic())
.collect(Collectors.toList());
}
此代码包含的信息肯定比:
filter(allCars, true, false, true);
对于更动态的解决方案,您可以创建一个MyFilter
类,该类具有active
属性和filter
谓词:
public class MyFilter<T> {
private boolean isActive;
private Predicate<T> filter;
// constructor and/or getter and setter
}
并使用以下内容筛选您的列表:
List<MyObject> result = objects.stream()
.filter(o -> filters.stream().allMatch(f -> f.test(o)))
.collect(Collectors.toList());
List result=objects.stream()
.filter(o->filters.stream().allMatch(f->f.test(o)))
.collect(Collectors.toList());
如果您只想匹配一个筛选器,可以使用anyMatch
而不是allMatch
。要否定结果,可以使用noneMatch
发布一些伪代码吗?如果您关心短而漂亮的代码,请使用kotlin。您可以使用列表上的筛选器或smth。例如,选中此项nna现在编辑问题。看看我的例子,@ardzy
.filter((Car car) -> onlyElectric ? car.isElectric() : true)
public enum CarFilter {
Electric, AllWheelsDrive, Automatic
}
public static List<Car> filter(
List<Car> allCars,
CarFilter... filters)
{
EnumSet<CarFilter> set = EnumSet.noneOf(CarFilter.class);
Collections.addAll(set, filters);
return allCars.stream()
.filter((Car car) -> !set.contains(CarFilter.Electric) || car.isElectric())
.filter((Car car) -> !set.contains(CarFilter.AllWheelsDrive) || car.isAllWheelsDrive())
.filter((Car car) -> !set.contains(CarFilter.Automatic) || car.isAutomatic())
.collect(Collectors.toList());
}
filter(allCars, CarFilter.Electric, CarFilter.Automatic);
filter(allCars, true, false, true);
public class MyFilter<T> {
private boolean isActive;
private Predicate<T> filter;
// constructor and/or getter and setter
}
List<MyFilter<MyObject>> filters = Arrays.asList(
new MyFilter<>(true, MyObject::isA),
new MyFilter<>(false, MyObject::isB),
new MyFilter<>(true, MyObject::isC)
);
List<MyObject> result = objects.stream()
.filter(o -> filters.stream().filter(MyFilter::isActive).allMatch(f -> f.getFilter().test(o)))
.collect(Collectors.toList());
public boolean test(T object) {
return !isActive || filter.test(object);
}
List<MyObject> result = objects.stream()
.filter(o -> filters.stream().allMatch(f -> f.test(o)))
.collect(Collectors.toList());