使通用函数适用于多个非重叠类型

时间:2015-08-27 10:00:26

标签: java generics

我试图编写一个从集合中随机抽取元素并将它们添加到新集合中的函数。因此,如果你想从{1,2,3,4,5}中抽取3个元素,你可以获得{5,3,4}。我想出了这个通用函数:

/**
 * Take a random sample without repeats of the specified size from a
 * collection. Note that if the collection you're sampling from contains
 * repeated elements, then the sample could also contain repeated elements.
 * Use a Set as an argument to avoid this.
 *
 * @param <T> The type of objects in the Collection
 * @param <E> The type of the collection
 * @param collection The collection
 * @param size The sample size of elements which you wish to extract from
 * the collection
 * @param factory A factory method for the collection E. Call with
 * "new::ArrayList" or something similar.
 * @return A random sample of the collection consisting of 'size' elements
 * without repeats (unless the original collection contained repeats).
 * @throws IllegalArgumentException if size is larger than the collection.size().
 */
public static <T, E extends Collection<T>> E drawRandomlyWithoutReplacement(List<T> collection, int size, Supplier<E> factory) {
    if (size > collection.size()) {
        throw new IllegalArgumentException("The sample size cannot be greater than the size of the collection.");
    }

    E list = factory.get();
    for (int i = 0; i < size; i++) {
        int r = MathUtils.randomInt(0, collection.size() - 1);
        list.add(collection.remove(r));
    }
    return list;
}

不幸的是,如果你删除它,Collection接口没有一个从集合中返回一个元素的函数,但是List和Vector(以及其他)确实有它。有没有办法让这个功能适用于Lists和Vectors而不必超载3次?我尝试将第一个参数设为C类型C extends List<T> | Vector<T>,但遗憾的是这并不起作用。

1 个答案:

答案 0 :(得分:1)

List,ArrayList,Vector如何是子类,它定义了

E remove(int index)//删除并返回

请参阅http://docs.oracle.com/javase/7/docs/api/java/util/List.html

感谢Marco指出,我最初建议使用AbstractList