我有一个元组列表,我想找到具有最大 x
值的元组。在存在多个最大 x
值的情况下,我想随机选择一个。我不知道如何实现这个随机选择功能。以下是我到目前为止的代码:
public void testSelectRandomFromLargestVals() {
List<Tuple<Integer, String>> list = new ArrayList<>();
list.add(new Tuple<>(5, "five-1"));
list.add(new Tuple<>(2, "two"));
list.add(new Tuple<>(3, "three"));
list.add(new Tuple<>(5, "five-2"));
list.add(new Tuple<>(5, "five-3"));
Optional<Tuple<Integer, String>> largestTuple = list.stream().max((t1, t2) -> Integer.compare(t1.x, t2.x));
System.out.println("Largest tuple is: " + largestTuple.get().x + " value is: " + largestTuple.get().y);
}
public class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tuple<?, ?> tuple = (Tuple<?, ?>) o;
if (!x.equals(tuple.x)) return false;
return y.equals(tuple.y);
}
@Override
public int hashCode() {
int result = x.hashCode();
result = 31 * result + y.hashCode();
return result;
}
}
最佳答案
事实证明Misha's一次性随机选择器(干得好,+1)可以与我的一次性最大值收集器结合使用 other answer到一个单一的 Collection 家。这允许在一次通过中从最大元素集中选择一个随机元素。
这是合并后的收集器:
static <T> Collector<T, ?, Optional<T>> rndMax(Comparator<? super T> cmp) {
class RndMax {
T val;
int cnt;
void add(T t) {
int c;
if (cnt == 0 || (c = cmp.compare(t, val)) > 0) {
cnt = 1;
val = t;
} else if (c == 0) {
cnt++;
if (ThreadLocalRandom.current().nextInt(cnt) == 0) {
val = t;
}
}
}
RndMax merge(RndMax other) {
if (cnt == 0) {
return other;
}
if (other.cnt == 0) {
return this;
}
int c = cmp.compare(val, other.val);
if (c < 0) {
return other;
} else if (c > 0) {
return this;
} else {
cnt += other.cnt;
if (ThreadLocalRandom.current().nextInt(cnt) < other.cnt) {
val = other.val;
}
return this;
}
}
Optional<T> finish() {
return cnt == 0 ? Optional.empty() : Optional.of(val);
}
}
return Collector.of(RndMax::new, RndMax::add, RndMax::merge, RndMax::finish);
}
你会像这样调用它:
List<Tuple<Integer,String>> list = ... ;
Optional<Tuple<Integer,String>> max =
list.stream().collect(rndMax(Comparator.comparingInt(t -> t.x)));
关于java - 如何选择集合中最大的元素之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35997182/