假设我有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;
}
答案 0 :(得分:0)
这种通用方法方法的主要问题是您不知道在每个列表元素上调用哪个方法进行检查。此外,您可以轻松地想象其他布尔测试,而不仅仅是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));
答案 1 :(得分:0)
您可以与功能结合使用。
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;
}
答案 2 :(得分:0)
List是java Collection接口的扩展,因此您可以通过覆盖equals方法进行大量自定义,以便您的contains方法可以按照您的意愿运行。你最终会做喜欢这样的事情:
@Override
public boolean equals(Object o){
if(o instanceof String){
String toCompare = (String) o;
return id.equals(toCompare);
}
return false;
}
答案 3 :(得分:0)
请检查下面的(工作)示例。通过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());
}
}
答案 4 :(得分:0)
你可以有这样的东西
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方法。
虽然这适用于String
,Integer
等类型,其中equals
已被覆盖。