如何创建可填充并返回现有或新Collection的通用方法?

时间:2018-09-20 08:43:11

标签: java generics

我目前正在开发一个存储库,该库可让用户将对象持久保存到外部存储中。我想添加对列表和集合的支持,所以添加了如下功能:

public <E extends Persistable> List<E> readList(String fileName, List<E> defaultValue)
public <E extends Persistable> Set<E> readSet(String fileName, Set<E> defaultValue)

现在,我认为为每种类型的Collection添加支持会很好。我想到了这样的事情:

public <C extends Collection<E>, E extends Persistable> C readCollection(String fileName, C defaultValue)

我的问题如下:如果用户调用readCollection(FILE, collection)并传递非null collection作为第二个参数,我可以使用它来将存储的项目添加到该collection。但是,如果用户之前已经存储了项目并通过null作为第二个参数,则必须创建collection的新实例。在Java中甚至有可能吗?

1 个答案:

答案 0 :(得分:0)

您可以传递Collection而不是传递默认的Supplier<C>实例:

public <C extends Collection<E>, E extends Persistable> C readCollection(String fileName, Supplier<C> supplier)
{
    C collection = supplier.get();
    ...
    return collection;
}

现在,您可以使用Supplier<C>创建Collection的实例。

您可以使用以下方法调用该方法:

readCollection(name, ArrayList::new)

或:

readCollection(name, HashSet::new)

如果仍然需要向现有Collection实例中添加元素的功能,则可以创建两个方法-readCollectionreadNewCollection

作为替代,您可以保留单个C readCollection(String fileName, C defaultValue)方法,并确定在将null作为第二个参数传递时要创建哪个实例。例如,您可以确定默认类型为ArrayList

顺便说一句,即使您保留了最初的两个方法readListreadSet,您也会遇到同样的问题-因为readSet可以返回任何Set的实现,所以如果第二个参数是null,则必须决定使用哪个Set实现。