簡體   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