我有一个域类(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"。。。
不管怎样,回到你的问题上来,你想做的是:
- 您有
List<Domain>
- 您希望将列表中的每个域转换为一个Bean(通过使用一些util方法(
- 将生成的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());
}