![](/img/trans.png)
[英]How to write a generic java method to return value with null check?
[英]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或Integer
或BigDecimal
或BigInteger
)的列表,並檢查列表中是否存在單個參數,並且返回布爾值?
任何幫助將不勝感激。 謝謝
我在想是否可以有這樣的方法:
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;
}
請檢查以下(工作)示例。 通過讓Student
從ObjectWithId<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
String
, Integer
等類型將是很好的選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.