繁体   English   中英

如何编写一种Java通用方法来检查通用列表中的值?

[英]how to write one java generic method to check value in generic list?

假设我有一个Student班:

public class Student {
    private String id;
    private String firstName;
    private String lastName;
    //gettter and setter
}

我将有Student名单:

List<Student> list; //this includes all students

现在,当我检索“ Student详细信息”对象时,我将仅具有该id并需要检查此id是否在上面提供的列表中。 我可以使用以下简单的Java轻松实现此目的:创建一个将列表和学生id作为参数并检查列表中是否存在该方法的方法:

public static boolean valueExistInList(List<Student> list, String studentId) {
    if (StringUtils.isNotBlank(studentId)) {
        for (Student stu : list) {
            if (studentId.equals(stu.getId())) {
                return true;
            }
        }
    }
    return false;
}

但是我的问题是:我是否还可以使用Java generics方法实现相同的功能,该方法将获取任何类型的对象和单个值参数(String或IntegerBigDecimalBigInteger )的列表,并检查列表中是否存在单个参数,并且返回布尔值?

任何帮助将不胜感激。 谢谢

我在想是否可以有这样的方法:

public static <T, U> boolean valueExistInList(List<T> list, U studentId) {
    boolean exists = false;
    //looping and checing whether studentId exists in list or not and 
    //then returning boolean value
    for(T t: list){
        //check studentId exists in list or not
        //if exists then return exists = true
        return exists;
    }
    return exists;
}

这种通用方法的主要问题在于,您不知道要在每个列表元素上调用哪种方法进行检查。 此外,您可以轻松想象其他布尔测试,不仅equals (而且不仅仅针对字符串)。

因此,您可以再退一步:让您的方法的调用者确定应在循环中进行的布尔测试。 您可以将其表示为接口:

interface BooleanExpression<T> { boolean test(T arg); }

您的通用方法现在更改为:

public static <T, U> boolean valueExistInList(List<T> list, BooleanExpression<T> tester) {
    for(T t: list) {
        if (tester.test(t)) return true;
    }
    return false;
}

您现在可以这样调用此方法:

List<Student> list = ...
final String studentId = ...
boolean result = valueExistsInList(list, new BooleanExpression<Student>() {
    @Override public boolean test(Student arg) {
         return arg.getId().equals(studentId);
    }
});

话虽如此……Java 8提供了这样的接口。 它称为Predicate 它非常适合新的Stream API 所以你现在可以写

List<Student> list = ...
String studentId = ...
boolean result = list.stream().anyMatch(s -> s.getId().equals(studentId));

您可以与功能结合使用。

public static <T> boolean valueExistInList(List<T> list, Predicate<T> predicate) {
    return list.stream().anyMatch(predicate);   
}

您可以这样称呼它:

valueExistsInList(students, s -> s.getId().equals(studentId));

要么:

valueExistsInList(cars, c -> c.getBrand().equals("Tesla"));

实际上,即使没有函数,您也可以执行以下操作:

boolean exists = students.stream().anyMatch(s -> s.getId().equals(studentId));

Java 7

public interface Predicate<T> {
    boolean test(T t);
}

然后像这样调用您的函数:

valueExistInList(students, new Predicate<Student>() {
    boolean test(Student s) {
        return s.getId().equals(studentId);
    }
});

然后函数valueExistsInList变为:

public static <T> boolean valueExistInList(List<T> list, Predicate<T> predicate) {
    for (T t : list) {
        if (predicate.test(t)) {
            return true;
        }
    }
    return false;   
}

List是Java Collection接口的扩展,因此您可以通过覆盖equals方法来进行很多自定义,以便您的contains方法将按您的意愿运行。 this: 你最终会做的事情:

@Override
public boolean equals(Object o){
    if(o instanceof String){
        String toCompare = (String) o;
        return id.equals(toCompare);
    }
    return false;
}

请检查以下(工作)示例。 通过让StudentObjectWithId<U>中覆盖(其中U是id的类型),您可以使用通用方法检查id(在Util类中)

public class Test
{
  public static void main(String[] args){
     Student s = new Student();
     s.setId("studentId1");

     System.out.println(Util.hasCorrectId(s, "studentId1"));
  }
}

public class ObjectWithId<U>
{
   private U id;

  public U getId(){
    return id;
  }

  public void setId(U id){
    this.id = id; 
  }
}

public class Student extends ObjectWithId<String>
{

}

public class Util {

  public static <U> boolean valueExistInList(List<ObjectWithId<U>> list, U id) {

        for (ObjectWithId<U> obj : list) {
            if(hasCorrectId(obj, id)) return true;
        }

        return false;

  }

  public static <U> boolean hasCorrectId(ObjectWithId<U> obj, U id){
    return id.equals(obj.getId()); 
  }


}

你可以有这样的东西

public static <T, U> boolean valueExistInList(List<T> list, U input) {
for(T t: list)
{
    if (input.equals(t.getU)) // getU method should be there in T 
    return true;
}
return false;
}

但是在传递自定义类型时必须小心。 您必须重写equals方法。

尽管这对于已经覆盖了equals StringInteger等类型将是很好的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM