如果您只想进行一次(或几次)查找,那么answer by @fabian 很好。
但是,如果您要经常这样做,那么该解决方案执行的顺序搜索效率不高。
要获得更有效的解决方案,您需要更有针对性的查找,因此您需要按累积机会来组织数据。这可以使用二进制搜索作为数组来完成,也可以通过累积机会作为NavigableMap 来完成。
使用NavigableMap,例如TreeMap,然后您可以使用higherEntry(K key) 查找所选对象:
返回与严格大于给定键的最小键关联的键值映射,如果没有这样的键,则返回null。
所以,这里是示例代码:
public class MyObj {
private final String name;
private final int weight;
public MyObj(String name, int weight) {
this.name = name;
this.weight = weight;
}
public String getName() {
return this.name;
}
public int getWeight() {
return this.weight;
}
@Override
public String toString() {
return this.name;
}
public static void main(String[] args) {
// Build list of objects
List<MyObj> list = Arrays.asList(
new MyObj("A", 2),
new MyObj("B", 6),
new MyObj("C", 12)
);
// Build map keyed by cumulative weight
NavigableMap<Integer, MyObj> weighedMap = new TreeMap<>();
int totalWeight = 0;
for (MyObj obj : list) {
totalWeight += obj.getWeight();
weighedMap.put(totalWeight, obj);
}
System.out.println(weighedMap);
// Pick 20 objects randomly according to weight
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
int pick = rnd.nextInt(totalWeight);
MyObj obj = weighedMap.higherEntry(pick).getValue();
System.out.printf("%2d: %s%n", pick, obj);
}
}
}
样本输出
{2=A, 8=B, 20=C}
14: C
10: C
9: C
5: B
11: C
3: B
1: A
0: A
1: A
7: B
4: B
11: C
17: C
15: C
4: B
16: C
9: C
17: C
19: C
2: B