如何用Java包装Collection的每个对象?

时间:2014-02-05 23:03:59

标签: java collections wrapper

我有一个类Foo,我为此创建了一个等价包装类WrappedFoo,以便在程序的某些部分更改其equals()合约。

我需要在很多地方将Foo个对象转换为WrappedFoo个对象,反之亦然。但我还需要将CollectionFoo的{​​{1}}从一个转换为另一个WrappedFoo。有什么方法可以通用的方式实现这一目标吗?

基本上我想要一个这样的方法:

public static Collection<WrappedFoo> wrapCollection(Collection<Foo> collection)

问题在于我不知道将使用哪种Collection实现,并且我希望为生成的Collection保留相同的实现。

4 个答案:

答案 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