gpt4 book ai didi

java - 使泛型函数适用于多个非重叠类型

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:10:01 26 4
gpt4 key购买 nike

我正在尝试编写一个函数,该函数从集合中随机抽取元素并将它们添加到新集合中。所以如果你想从 {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 接口(interface)没有一个函数可以在您删除它时从集合中返回一个元素,但是 List 和 Vector(以及其他)有它。有没有一种方法可以让这个函数适用于列表和 vector ,而不必重载它 3 次?我尝试将第一个参数设为 C 类型其中 C extends List<T> | Vector<T>但不幸的是,这没有用。

最佳答案

Collection 接口(interface)不能删除,但它的Iterator

public static <T, E extends Collection<T>> E drawRandomlyWithoutReplacement(Collection<T> collection, int size,
Supplier<E> factory) {
final int colSize = collection.size();
if (size > colSize) {
throw new IllegalArgumentException("The sample size cannot be greater than the size of the collection.");
} else if(size == 0) {
return factory.get();
}

Random rand = new Random();
Set<Integer> sampleIndices = new TreeSet<>();
while (sampleIndices.size() < size) {
sampleIndices.add(rand.nextInt(colSize));
}

E result = factory.get();

Iterator<T> collectionIterator = collection.iterator();
Iterator<Integer> indexIterator = sampleIndices.iterator();
int sampleIndex = indexIterator.next();
for (int i = 0; i < colSize; i++) {
T sample = collectionIterator.next();
if (i == sampleIndex) {
result.add(sample);
collectionIterator.remove();
if (indexIterator.hasNext()) {
sampleIndex = indexIterator.next();
} else {
break;
}
}
}
return result;
}

关于java - 使泛型函数适用于多个非重叠类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32246320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com