我正在尝试编写一个函数,它从一个集合中随机抽取元素并将它们添加到一个新元素中。因此,如果您想从{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接口不具有从集合返回元素的功能,如果你删除它,但名单和Vector(等等)也有它。有没有一种方法可以使这个函数适用于列表和向量,而不必重载3次?我尝试使第一个参数是C
,其中C extends List<T> | Vector<T>
,但不幸的是这并没有工作。
哪一个是用于'Set'? –
你的JavaDoc说:“使用Set作为参数来避免这个[重复]”。所以不需要创建不同的方法,或者我错了吗? – Flown
@DraganBozanovic,你是对的设置没有这个方法。 –