Java 如何查找包含对象的ArrayList

Java 如何查找包含对象的ArrayList,java,Java,我有一个返回对象的方法,比如 public static Object login(DataManager dataManager, String userName, String password) ArrayList<LoginCredentialsBean> loginCredentialsList = new ArrayList<LoginCredentialsBean>(); String authenticated

我有一个返回对象的方法,比如

public static Object login(DataManager dataManager, String userName, String password)       
    ArrayList<LoginCredentialsBean> loginCredentialsList = new ArrayList<LoginCredentialsBean>();       
    String authenticated = "false";     
    Connection connection = null;       
    try {           
        connection  = dataManager.getConnection();          
    } catch (Exception e) {         
         return ("Having problem in connectiong to databaste: " + e.getMessage());          
    }       
    if (connection != null) {           
         try {                                       
             ...                     
             try {                   
                 ResultSet rs = prepStatement.executeQuery();                   

                 try {                      
                     while (rs.next()) {
                         ...                             
                         loginCredentialsList.add(new LoginCredentialsBean(roleId, orgaCode, passwordExpiryDate, date, status, language));                                                          
                        authenticated = "true";                          
                     } //end of while()                                                  
                 } finally {                     
                     rs.close();                     
                 }                   
             } finally {
                 prepStatement.close();                  
             }                
             if (authenticated.equals("true")) {                     
                updateUserLogByInserting(connection, userName);                  
             }

         } catch(SQLException e) {               
             System.out.println("Could not login from dataabse:" + e.getMessage());              
         } finally {                 
             dataManager.putConnection(connection);                          
         }                  
    }       
    if (authenticated.equals("true")) {                 
        return loginCredentialsList;            
    } else {        
        return authenticated;           
    }       
} //end of login()
我想问一下,我使用的条件是
ArrayList
。如何检查包含LoginCredentialsBean对象的ArrayList。就像我使用

if (result instanceof ArrayList<LoginCredentialsBean>) {

}
if(ArrayList的结果实例){
}
我得到一个错误

Can not perform instanceof check against parameterized type ArrayList<LoginCredentialsBean>. Use the form ArrayList<?>
无法对参数化类型ArrayList执行instanceof check。使用ArrayList表单
我想检查ArrayList的实例,ArrayList是否有LoginCredentialsBean


谢谢。

参数化的类型信息在编译时被删除,而
的instanceof
在(fanfare)运行时被解析-这就是为什么会出现该错误

您可以做的是迭代
列表中的元素
实例
中的元素


干杯,

简而言之,你不能。泛型是通过类型擦除实现的——它们实际上是一种编译时语法糖,以确保您不会将
整数
放入
列表

然而,运行时对象本身只是原始类型。
ArrayList
的实例不知道它是一个
ArrayList
(或者更确切地说,它被分配给了一个具有该泛型类型的变量)。因此,当您使用反射查询它时,您无法获得任何泛型类型信息

我可以想到两大类解决方案。一种是迭代列表内容并检查其动态类型——例如,如果第一个元素是
LoginCredentialsBean
,那么可以合理地假设您有一个
list
。但这对空列表不起作用,这可能是一个问题,并且可能会产生误报(例如,
List allParameters
可能碰巧有一个
LoginCredentialsBean
作为其第一个元素…)

另一种方法是显式地传递元数据对象,因此在本例中,您将从
login
方法返回
对象
,以及描述对象类型的标记。这可能是一个简单的枚举常量;或者转到另一个极端,您可以使标记具有一般类型,这样编译器就可以根据您返回的内容的类型进行检查,并确保标记的类型正确

但无论如何,
instanceof
太少(信息),太晚了


请注意,您的
登录方法看起来。。。古怪的我认为它根本不应该返回
对象
,因为这只是一个懒惰的行为,完全颠覆了静态类型系统,这将在这里帮助您。相反,我认为它应该返回一个
列表
,其中包含与给定登录相关的凭据

您有三条不同的返回路径。第一个是连接到数据库时遇到异常-在这种情况下,您应该抛出异常!返回包含错误详细信息的字符串是非常不典型和令人困惑的-异常情况应该作为
异常处理
,这就是它们的用途

另外两种情况下,您可以查找最终结果。对于失败的登录案例,我只会返回一个空列表(即此用户名/密码没有任何凭据),而在成功登录期间返回填充的列表

如果您强烈希望能够区分登录失败和成功登录(没有凭据),那么可以返回一个复合对象,例如:

class LoginStatus {
    final boolean authenticated;
    final List<LoginCredentialsBean> credentials;
}
类登录状态{
最终布尔认证;
全权证书最后清单;
}

无论哪种方式,调用者都确切地知道他们得到了什么,并且可以适当地对其调用方法,而不必调用
instanceof
和typecast。

您必须对其进行两次检查

if (result instanceof ArrayList<?>) {
 System.out.println("ArrayList instance");
 //cast
 ArrayList<LoginCredentialsBean> list = (ArrayList<LoginCredentialsBean>) result;

  ///..check if list contains LoginCredentialsBean
 for(int i=0; i<list.size(); i++){
  if(list.get(i) instanceof LoginCredentialsBean){
   System.out.println("LoginCredentialsBean instance");
  }  
 }
}     
if(ArrayList的结果实例){
System.out.println(“ArrayList实例”);
//铸造
ArrayList=(ArrayList)结果;
///..检查列表是否包含LoginCredentialsBean

对于(inti=0;i来说,没有类似“ArrayList包含LoginCredentialsBean”这样的东西 ArrayList始终包含对象

必须迭代列表并检查每个对象:

for (Object o: result) {
     if (!(o instanceof LoginCredentialsBean)) {
           //Fail
     }
}

您可以使用
contains(对象o)
检查ArrayList是否包含您的对象。使用
instanceof List
检查给定对象是否为列表。由于运行时类型擦除,列表的通用类型将不可用

如果您的
登录
方法返回一个
对象
类型,则无法按您尝试的方式进行检查。 由于类型擦除,类型参数仅在编译时存在。您需要检查返回的对象是否是
列表
集合
或只是
Iterable
,然后通过它进行迭代并检查每个项,如果它是
LoginCredentialsBean
的实例

但是,您的代码是一个糟糕的设计示例。返回
字符串或列表的方法是错误的。要使其正确,请执行以下操作:

  • 使其返回
    列表
  • 如果身份验证失败,则引发已检查的异常
公共静态列表登录(DataManager DataManager、字符串用户名、字符串密码)引发AuthenticationException{…}


注意:使用
boolean
来保存逻辑数据,而不是
“true”
“false”
字符串。

hhmm谢谢。说实话,是的,这很奇怪,谢谢你指点我:)首先,我认为我应该在我的LoginCredentialBean中创建一个布尔字段,但后来我认为LoginCredentialBean实例应该只在用户成功进行身份验证时创建,然后我得到了这个糟糕的设计代码:)。无论如何,我在bean中创建布尔字段,首先它是false,在成功进行身份验证时,我将它设置为true并返回LoginCredentialBean的列表。您觉得可以吗?我可以假设,如果我的列表为空,则用户有fa
if (result instanceof ArrayList<?>) {
 System.out.println("ArrayList instance");
 //cast
 ArrayList<LoginCredentialsBean> list = (ArrayList<LoginCredentialsBean>) result;

  ///..check if list contains LoginCredentialsBean
 for(int i=0; i<list.size(); i++){
  if(list.get(i) instanceof LoginCredentialsBean){
   System.out.println("LoginCredentialsBean instance");
  }  
 }
}     
for (Object o: result) {
     if (!(o instanceof LoginCredentialsBean)) {
           //Fail
     }
}