假设我们有像Person这样的类
Person.java
public class Person{
String lastName;
String code;
String name;
int age;
public Person(String lastName, String code, String name, int age) {
this.lastName = lastName;
this.code = code;
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getLastName() {
return lastName;
}
public String getCode() {
return code;
}
public String toString() {
return String.format("Person(%s,%s,%s,%s)", name, lastName, code, age);
}
}
假设有另一个类创建Person
列表FilterList.java
public class FilterList {
public static void main(String[] args) {
List<Person> list = Arrays.asList(
new Person("Oscar", "ali soltani", "15-01", 0x20),
new Person("Reyes", "javan", "16-01", 0x30),
new Person("Java", "javan", "18-01", 20),
new Person("hamid", "javan", "18-01", 20)
);
int age = 0 ;
String name = "";
String code = "";
String lname = "javan";
for (Person p : list) {
if (((Integer.toString(age).isEmpty() || age ==0) ? true :p.getAge() == age)
&& (code.isEmpty() ? true : p.getCode().equals(code))
&&(lname.isEmpty() ? true :p.getLastName().equals(lname)) &&
(name.isEmpty() ? true :p.getName().equals(name)) ) {
System.out.println(p);
}
}
}
}
同样,假设我们想要按每个字段或字段的任意组合过滤Person列表,例如如果字段名称可用,我们会得到结果,例如名称等于给定名称的每个人,例如
name = "ali";
所以,你应该编写如下代码:
for (Person p : list) {
if(p.getName().equals(name)){
System.out.println(p);
}
}
因此输出如下:
Person(hamid,javan,18-01,20)
如果要过滤任何字段上的列表,则应编写相同的代码,使用 if 语句和合适的getter方法和参数来检查相等性。类中有四个字段 Person 我们应该为每个字段编写四个if语句。 另一方面,如果要过滤任何字段组合的列表,您应该像以前一样编写。值得注意的是,如果班级人中有4个字段,我们应该写4个!如果像下面的代码一样支持每个字段组合:
for (Person p : list) {
if(p.getName().equals(name)){ // filter on name
System.out.println(p);
} else if(p.getLastName().equals(lname)){ //filter on lastname
System.out.println(p);
} else if(){ // rest of the field same as above
.
.
.
}else if(p.getName().equals(name) && p.getLastName().equals(lname)){
//filter on name and lastname
System.out.println(p);
}
// rest of the code for other combinations
.
.
.
else if(p.getName().equals(name) &&
p.getLastName().equals(lname) &&
p.getCode().equals(code) &&
p.getAge() == age){
//filter on all fields
System.out.println(p);
}
}
对于有几十个字段的情况,这将是非常困难的并且容易出错,N!具有N个字段的类的不同状态。
我使用解决了这个问题? :运算符将其与if语句结合使用,使用任意组合过滤列表,只有
for (Person p : list) {
if (((Integer.toString(age).isEmpty() || age ==0) ? true :p.getAge() == age)
&& (code.isEmpty() ? true : p.getCode().equals(code))
&&(lname.isEmpty() ? true :p.getLastName().equals(lname)) &&
(name.isEmpty() ? true :p.getName().equals(name)) ) {
System.out.println(p);
}
}
它完美无缺。
有没有更好的方法来回答这个问题?
答案 0 :(得分:2)
您可以覆盖equals
(如果您对一条规则非常满意),或者您可以更灵活地为您的对象创建特殊的Comparator。只记得比较器返回-1,0,1。所以你应该使用一个via桥,它转换0 - &gt; true和[-1,1] - &gt;假。在这种实现方式中,您将拥有通过特殊规则比较对象的单独逻辑(覆盖equals
,您只能覆盖单个规则案例)。
为了满足您的需求,您可以使用模式chain of responsibility处理许多特殊处理程序。如果您使用了一个,如果条件已经处理并且不应该考虑其他条件,请不要忘记打破链条。
每个案例创建不同规则的缺点是代码增加,但好处是灵活的解决方案。你有很好的工具来改变连锁服务。您可以在任何地方使用此链,也可以使用现有rules
创建另一个链。如果您需要改进conditions
,则不会更改常规代码部分。链可以单独隔离的方式进行测试。
如果您不了解GoF设计模式,我建议您在stackoverflow上查看有关wiki的一些信息(非常好的示例和解释)。
答案 1 :(得分:0)
尝试Java 8流和过滤器,如下所示:
List<Person> list = new ArrayList<>();
Person p1 = new Person("Mehdi");
Person p2 = new Person("Mark");
Person p3 = new Person("Cris");
list.add(p1);list.add(p2);list.add(p3);
List<Person> filteredList = list.stream().filter(member -> "Mehdi".equals(member.name)).collect(Collectors.toList());
System.out.println(filteredList.get(0).name);