我有一个类Foo
,我为此创建了一个等价包装类WrappedFoo
,以便在程序的某些部分更改其equals()
合约。
我需要在很多地方将Foo
个对象转换为WrappedFoo
个对象,反之亦然。但我还需要将Collection
和Foo
的{{1}}从一个转换为另一个WrappedFoo
。有什么方法可以通用的方式实现这一目标吗?
基本上我想要一个这样的方法:
public static Collection<WrappedFoo> wrapCollection(Collection<Foo> collection)
问题在于我不知道将使用哪种Collection
实现,并且我希望为生成的Collection
保留相同的实现。
答案 0 :(得分:2)
使用Reflection API,您可以执行以下操作(请注意方法名称中的0
):
public static Collection<WrapperFoo> wrapCollection0(Collection<Foo> src)
{
try
{
Class<? extends Collection> clazz = src.getClass();
Collection dst = clazz.newInstance();
for (Foo foo : src)
{
dst.add(new WrapperFoo(foo));
}
return dst;
} catch(Exception e)
{
e.printStackTrace();
return null;
}
}
现在使用上面的方法实现一大堆单行重载方法(注意调用中的0
):
public static ArrayList<WrapperFoo> wrapCollection(ArrayList<Foo> src)
{
return (ArrayList<WrapperFoo>) wrapCollection0(src);
}
public static Vector<WrapperFoo> wrapCollection(Vector<Foo> src)
{
return (Vector<WrapperFoo>) wrapCollection0(src);
}
...
答案 1 :(得分:2)
Collection-Interface保证了&#34; boolean addAll(Collection c)&#34; -method的存在。 我只是沿着这条线尝试一下:
public static Collection<WrappedFoo> wrapFoos(Collection<Foo> col) {
Class<?> colClass = col.getClass();
Collection<WappedFoo> newCol = colClass.getConstructor().getInstance();
newCol.addAll(col);
return newCol;
}
答案 2 :(得分:1)
Google Guava库中的Collections2.transform可能会提供您正在寻找的功能。
你应该能够在WrappedFoo中传递一个包含Foo元素的Function。主要问题是新集合是否可以作为原始集合的视图(因此它不会与原始集合具有相同的实现)。
答案 3 :(得分:0)
问这个问题已经好几年了,但是自从Java 1.8以来,您可以使用流来实现这一目标:
public static Collection<WrappedFoo> wrapCollection(Collection<Foo> collection) {
List<WrappedFoo> wrappedList = collection.stream().map(m -> new WrappedFoo(m)).collect(Collectors.toList());
return new ApiBulkResponse<Wrapper>(wrappedList);
}
您只需要在WrappedFoo
类中提供一个构造函数即可将Foo
对象转换或封装为WrappedFoo
。