如何在java中编写泛型方法,该方法接受任意两个对象的列表并返回列表



我有一个域类(DB(:

public class PersonDoamin {
private String name;
private String age;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getAge() {
    return age;
}
public void setAge(String age) {
    this.age = age;
}
}

我还有模型类:

public class PersonBean extends PersonDoamin {
}

因此,当我转到DAOImpl类并查询List并将此列表转移到List并返回给用户时,我有ListgetAllPerson((的接口方法。所以当我从List传输所有数据时,我的问题就在这里。这里我有一些实用的方法,可以像这样从一个bean复制到另一个bean:

List<PersonDoamin> list = PersonDAO.getAllPersons();
List<PersonBean> pbList = new ArrayList<PersonBean>();
/* this below logic is pretty much in the all DAO impl*/
for(PersonDoamin p : list){
PersonBean pb = new PersonBean();
CopyHelper.copyBean(p, pb);
pbList.add(pb);
}
return pbList;

我们可以用某种通用方法来代替循环、复制和添加到另一个列表并返回部分吗?这种方法将接受任何对象两个列表并循环通过一个列表,然后将其添加到传递的另一个list参数并返回它

public static <T> List<T> listToArray(List<T> list,List<T> list2) {
    for(T element : list){
        list2.add(element);
    }
    return list2;
}
public static void main(String[] args) {
    List<PersonDoamin> personList = new ArrayList<PersonDoamin>();
    PersonDoamin p = new PersonDoamin();
    p.setName("aj");
    p.setAge("25");
    personList.add(p);
    List<PersonBean> personBeansToReturn = new ArrayList<PersonBean>();
    Test.listToArray(personList , personBeansToReturn );
}

有点偏离主题,你的设计似乎有点奇怪,你有"Domain"类和"Bean"类,并且"Bean"扩展了"Domain"。。。

不管怎样,回到你的问题上来,你想做的是:

  1. 您有List<Domain>
  2. 您希望将列表中的每个域转换为一个Bean(通过使用一些util方法(
  3. 将生成的Beans放入列表中并返回

让我们一步一步地进行。

(顺便说一句,您编写的listToArray方法与原始循环不对齐,因为它不执行转换(第2点(。我猜是打字错误?(

(所有的psuedo代码,因为我手头没有编译环境。我想概念应该是正确的(


步骤1:个人的Util方法

原始util方法的一个最大问题是,将Parent对象实例放在List of Child中是非法的(自己应该很容易弄清楚原因(。

util方法应该如下所示:

List<PersonBean> toBeans(List<PersonDomain> domains) {
    List<PersonBean> beans = new ArrayList<>(domains.size());
    for (PersonDomain domain: domains) {
        PersonBean bean = new PersonBean(); 
        CopyHelper.copyBean(domain, bean);
        beans.add(bean);
    }
    return beans;
}

步骤2:使其通用

上面的问题是它只适用于Person。如果你想让它通用,你还需要提供将Domain转换为Bean的功能:

(假设您正在使用Java8,如果您使用的是旧版本,那么制作自己的界面应该很简单(

<D,B> List<B> toBeans(List<D> domains, Function<B,D> mapper) {
    List<PersonBean> beans = new ArrayList<>(domains.size());
    for (PersonDomain domain: domains) {
        beans.add(mapper.apply(domain));
    }
    return beans;
}

以便您可以通过以下方式使用:

return toBeans(personDomains, (domain) -> {
                         PersonBean bean = new PersonBean(); 
                         CopyHelper.copyBean(domain, bean);
                         return bean;
                     });

(如果在大多数情况下要使用CopyHelper方式,则可以考虑包装函数(

<D,B> List<B> toBeansByBeanCopy(List<D> domains, Class<B> beanClass) {
    return toBeans(domains, (domain)-> {
                         B bean = beanClass.newInstance(); 
                         CopyHelper.copyBean(domain, bean);
                         return bean;
                     });
}

以便您可以将其用作

return toBeansByBeanCopy(personDomains, PersonBean.class);

第3步:Java已经为您完成了

实际上,您在上面尝试做的事情,已经由Java在Java 8中提供了。你可以简单地做:

return personDomains.stream()
    .map(d -> {
        PersonBean bean = new PersonBean(); 
        CopyHelper.copyBean(domain, bean);
        return bean;
        })
    .collect(Collectors.toList());

如果lambda表达式是标准方法,那么您可以编写一个小方法来使用它。

return personDomains.stream()
    .map(BeanMapper.mapper(PersonBean.class))
    .collect(Collectors.toList());

(将实现作为练习(

如果您正在寻找在泛型类型上调用new的方法,您可以。您必须使用反射并在Class对象上调用newInstance。我不知道这对你来说是否可行。

此外,如果不使用一些重反射,我看不到任何实际实现bean复制方法的方法。在下面的例子中,我只是通过强制转换到所需的类来伪造。

public class GenericCopyTest
{
   public static void main( String[] args ) throws Exception
   {
      List<PersonDoamin> personList = new ArrayList<PersonDoamin>();
      PersonDoamin p = new PersonDoamin();
      p.setName( "aj" );
      p.setAge( "25" );
      personList.add( p );
      List<PersonBean> personBeansToReturn = new ArrayList<PersonBean>();
      copyAndDowncast( personList, personBeansToReturn, PersonBean.class );
      System.out.println( personBeansToReturn );
   }
   public static <T,U extends T> List<U> copyAndDowncast( List<T> from, 
           List<U> to, Class<U> type ) 
           throws InstantiationException, IllegalAccessException
   {
      for( T element : from ) {
         U nu = type.newInstance();
         copyBean( element, nu );
         to.add( nu );
      }
      return to;
   }
   private static <X,Y extends X> void copyBean( X from, Y nu ) {
      ((PersonBean)nu).setName( ((PersonDoamin)from).getName() );
      ((PersonBean)nu).setAge( ((PersonDoamin)from).getAge() );
   }
}
class PersonDoamin {
   private String name;
   private String age;
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public String getAge() {
       return age;
   }
   public void setAge(String age) {
       this.age = age;
   }
   @Override
   public String toString()
   {
      return "PersonDoamin{" + "name=" + name + ", age=" + age + '}';
   }
}
class PersonBean extends PersonDoamin {
   @Override
   public String toString()
   {
      return "PersonBean{" + getName() + ',' + getAge()+ '}';
   }
}

输出:

run:
[PersonBean{aj,25}]
BUILD SUCCESSFUL (total time: 0 seconds)

为什么不直接使用addAll()呢?它做你想做的事情,而且它已经是系统库的一部分了。

请记住,您可以将PersonBean添加到PersonDomain列表中,但不能反过来。

public class GenericCopyTest
{
   public static void main( String[] args ) {
      List<PersonDoamin> personList = new ArrayList<PersonDoamin>();
      List<PersonBean> personBeansToReturn = new ArrayList<PersonBean>();
      personList.addAll( personBeansToReturn );
      personBeansToReturn.addAll( personList );  // <-- FAILS
                                                 // No suitable method found
   }
}
class PersonDoamin {}
class PersonBean extends PersonDoamin {}

如果要将多个bean类放在同一列表中,用父类PersonDoamin创建列表怎么样?然后,您可以同时存储PersonDoamin和PersonBean类。

public static void main(String[] args) {
    List<PersonDoamin> personList = new ArrayList<PersonDoamin>();
    PersonDoamin p = new PersonDoamin();
    p.setName("aj");
    p.setAge("25");
    personList.add(p);
    // Changed here. PersonBean => PersonDoamin
    List<PersonDoamin> personBeansToReturn = new ArrayList<PersonDoamin>();
    Test.listToArray(personList, personBeansToReturn);
    // also you can insert PersonBean into the list
    personBeansToReturn.add(new PersonBean());
}

相关内容

最新更新