for循环查询很慢,效率低,数据量大的话手机会卡顿,所以用二分查询
下面是我自己的
直播间的在线用户列表和贡献值列表,最后合成一个总的在线用户列表且按照贡献值排序
1.遍历全部用户在线列表构造用户信息和贡献值的模型的列表。然后排序,再通过二分法遍历贡献值列表添加贡献值(替换贡献值),有一个人进来就(二分法去重,判断是否有)插入一个,有人出去就(二分法遍历查找下标)删掉,有人送礼收到回调就更新贡献值列表然后再从贡献值列表里面把值再通过二分法添加进总的列表
2.有人进房间,二分法遍历贡献值列表是否有这个用户,有就带上该用户信息和贡献值添加到总列表,没有就添加用户信息和0贡献值到总列表
3.自己统计贡献值列表,进来时就请求一遍贡献值列表,然后接收到贡献值回调就使用二分法往列表里面添加数据,最终得到贡献值列表,怎么添加,首先排序,然后用二分法查找总的贡献值列表里面有没有该用户,没有就直接添加,有就把值添加上去再排序
进来刷新,有人进来刷新,有人退出刷新,有人送礼刷新
//在线用户贡献值总列表,二分法去重
checkOnlineList(int userId) {
int left = 0;
int right = onLineContributeList.length - 1;
int targetIndex = -1;
while (left <= right) {
int middle = (left + right) ~/ 2;
if (onLineContributeList[middle].groupUserBean != null) {
if (onLineContributeList[middle].groupUserBean!.userID != null) {
if (onLineContributeList[middle].groupUserBean!.userID != '') {
if (int.parse(
onLineContributeList[middle].groupUserBean!.userID!) ==
userId) {
targetIndex = middle;
break;
} else if (int.parse(
onLineContributeList[middle].groupUserBean!.userID!) <
userId) {
left = middle + 1;
} else {
right = middle - 1;
}
}
}
}
}
return targetIndex;
}
下面是一个使用二分法查找Flutter对象类型的列表的示例代码:
class Person {
String name;
int age;
Person(this.name, this.age);
}
void main() {
List<Person> persons = [
Person("Alice", 28),
Person("Bob", 35),
Person("Charlie", 42),
Person("Dave", 19),
Person("Eve", 31),
Person("Frank", 46),
];
// 二分法查找年龄为 31 岁的人
int left = 0;
int right = persons.length - 1;
while (left <= right) {
int middle = (left + right) ~/ 2;
if (persons[middle].age == 31) {
print("${
persons[middle].name} is 31 years old.");
break;
} else if (persons[middle].age < 31) {
left = middle + 1;
} else {
right = middle - 1;
}
}
}
这是一个使用二分法在persons
列表中查找age
属性等于31
的Person
对象的示例代码。在二分法查找之前,我们需要将列表按照某种顺序排序。在这个例子中,我们默认使用对象的age
属性进行排序,因此列表中的Person
对象已经按照age
属性从小到大排序。
二分法查找的原理是每次将列表中间的元素与目标元素进行比较,如果相等则查找成功,如果目标元素较小,则在列表的左半部分进行查找,否则在列表的右半部分进行查找。每次查找都能排除掉一半的元素,因此时间复杂度为O(log n)
,比线性查找的时间复杂度O(n)
优秀很多。