如何编写一个java泛型方法来检查泛型列表中的值?
假设我有如何编写一个java泛型方法来检查泛型列表中的值?,java,list,generics,Java,List,Generics,假设我有学生课程: public class Student { private String id; private String firstName; private String lastName; //gettter and setter } 我将有学生的名单: List<Student> list; //this includes all students 但我的问题是:Java泛型方法是否也可以实现相同的功能,该方法将获取任何类型的对象
学生
课程:
public class Student {
private String id;
private String firstName;
private String lastName;
//gettter and setter
}
我将有学生的名单
:
List<Student> list; //this includes all students
但我的问题是:Java泛型
方法是否也可以实现相同的功能,该方法将获取任何类型的对象列表和单值参数(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;
}
public静态布尔值existinList(列表列表,U studentId){
布尔存在=假;
//循环并检查列表中是否存在studentId,以及
//然后返回布尔值
对于(T:列表){
//检查列表中是否存在studentId
//如果存在,则返回exists=true
回报存在;
}
回报存在;
}
这种通用方法的主要问题是,您不知道在每个列表元素上调用哪个方法进行检查。此外,您可以很容易地想象其他布尔测试,不仅仅是等于(而且不仅仅是字符串)
因此,您可以退一步:让方法的调用方决定应该在循环中进行什么布尔测试。您可以将其表示为一个接口:
interface BooleanExpression<T> { boolean test(T arg); }
可以与函数组合使用
public static <T> boolean valueExistInList(List<T> list, Predicate<T> predicate) {
return list.stream().anyMatch(predicate);
}
或:
事实上,即使没有函数,您也可以这样做,更直接的方式如下:
valueExistsInList(students, s -> s.getId().equals(studentId));
boolean exists = students.stream().anyMatch(s -> s.getId().equals(studentId));
valueExistInList(students, new Predicate<Student>() {
boolean test(Student s) {
return s.getId().equals(studentId);
}
});
Java 7
public interface Predicate<T> {
boolean test(T t);
}
List是java集合接口的一个扩展,因此您可以通过重写equals方法进行大量定制,这样您的contains方法就可以按照您的意愿运行。你最终会做这样的事情:
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;
}
请检查下面的(工作)示例。通过让Student
覆盖ObjectWithId
中的U
是id的类型,您可以使用通用方法检查id(在Util类中)
公共类测试
{
公共静态void main(字符串[]args){
学生s=新学生();
s、 setId(“学生1”);
System.out.println(Util.hasCorrectId(s,“studentId1”);
}
}
公共类ObjectWithId
{
私人身份证;
公共U getId(){
返回id;
}
公共无效设置id(U id){
this.id=id;
}
}
公共类学生使用ID扩展ObjectWithId
{
}
公共类Util{
公共静态布尔值ExistInList(列表列表,U id){
for(ObjectWithId对象:列表){
if(hasCorrectId(obj,id))返回true;
}
返回false;
}
公共静态布尔值hasCorrectId(ObjectWithId obj,U id){
返回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;
}
公共静态布尔值existinList(列表列表,U输入){
对于(T:列表)
{
if(input.equals(t.getU))//getU方法应该在t中
返回true;
}
返回false;
}
但是在传递自定义类型时必须小心。您必须重写equals方法
虽然这对于String
,Integer
等类型很好,但是equals
已经被覆盖。您可以更改数据结构吗?似乎您需要的是hashmap而不是列表您必须使用java反射来识别数据类型并使用此数据类型进行搜索。我无法实现此解决方案,因为我们没有升级到java 8。您仍然可以,但它必须使用匿名类,并且您必须创建自己的谓词
接口(非常简单)。我将添加一个示例来演示如何实现。是的,太糟糕了,我无法实现这一点,因为我们仍在使用java 7。我根据您的上述建议使其工作。ThanksList将具有一个属性,该属性将等于传递的T输入。@useDT在这种情况下,为了使其通用,您的T
类型应该具有约定(实现一个接口)。这样T
将有一个返回U
的方法,该方法将用于与输入进行比较。
boolean exists = students.stream().anyMatch(s -> s.getId().equals(studentId));
public interface Predicate<T> {
boolean test(T t);
}
valueExistInList(students, new Predicate<Student>() {
boolean test(Student s) {
return s.getId().equals(studentId);
}
});
public static <T> boolean valueExistInList(List<T> list, Predicate<T> predicate) {
for (T t : list) {
if (predicate.test(t)) {
return true;
}
}
return false;
}
@Override
public boolean equals(Object o){
if(o instanceof String){
String toCompare = (String) o;
return id.equals(toCompare);
}
return false;
}
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;
}