从geoQuery向recyclerView添加唯一项目



我创建了一个应用程序,显示我附近的用户项目。

我使用geoQuery找到靠近我的人,如果他们在我附近,我会在数据库中搜索他们拥有的项目,并用他们填充RecyclerView

我使用

List<DiscoverItems> items = new ArrayList<>();
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(Lat, Lon), Radius);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
String UserID = key;
if (!UserID.equals(auth.getUid())) {
db.collection("Users").document(UserID).collection("MyItems").get().addOnCompleteListener(task_count -> {
if (task_count.isSuccessful()) {
for (DocumentSnapshot document_near : task_count.getResult()) {
items.add(new DiscoverItems(document_near.getString("ItemID")));
}
}
});
}
discoverItemAdapter = new DiscoverItemAdapter(items, listener);
rv_NearMeItems.setAdapter(discoverItemAdapter);
}
@Override
public void onKeyExited(String key) {
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
}
@Override
public void onGeoQueryReady() {
}
@Override
public void onGeoQueryError(DatabaseError error) {
}
});

然而,我的问题是,如果一些用户有相同的物品,因为当我喜欢它有独特的物品时,它会在recyclerView中出现两次。

有没有什么解决方案可以让我先检查我的项目列表是否重复,然后再添加它们?

我试着做了以下事情:

List<DiscoverItems> items= new ArrayList<>();
Set<DiscoverItems> itemkset = new HashSet<>();
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(Lat, Lon), Radius);
geoQuery.addGeoQueryEventListener( new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
String UserID = key;
if (!UserID.equals( auth.getUid() )) {
db.collection( "Users" ).document( UserID ).collection( "MyItems" ).get().addOnCompleteListener( task_count -> {
if (task_count.isSuccessful()) {
for (DocumentSnapshot document_near : task_count.getResult()) {
itemset.add( new DiscoverItems( document_near.getString( "ItemID" ) ) );
}
}
} );
}
List<DiscoverItems> itemsWithoutDuplicates = new ArrayList<>(new HashSet<>(itemset));
for (DiscoverItems item: itemsWithoutDuplicates){
items.add(item);
}
discoverItemAdapter = new DiscoverItemAdapter(items, listener);
rv_NearMeItems.setAdapter(discoverItemAdapter);
}

但它不起作用,因为例如,如果我有两个用户,onKeyEntered将被调用两次。对于第一个用户,它将添加到itemset,比方说4个不相同的项目,一切都会好起来。然后它将调用第二个用户,第二个将添加3个不相同项目到项目集,一切都好起来。

我是不是错过了什么?因为使用上面的代码,我得到了多个项目。

谢谢

我不知道对象的复杂性,但您可以尝试从List<>int更改为Set<>。通常,Set是包含无重复元素的集合(例如,基于他们的哈希代码(。

1( 对象比较

首先,您必须重写DiscoverItems类中的equals()hashCode()才能使用基于哈希的集合(如HashSet(。

你可以在Android Studio中生成这些方法,并根据哪些字段选择你可以说";这两个对象是相同的";。有时不需要比较所有字段(例如,您可以只使用名称或某个ID(。

在您的情况下,您必须比较您传递给DiscoverItems类构造函数的这个字段。它可能看起来像那里:

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
DiscoverItems that = (DiscoverItems) object;
return Objects.equals(itemID, that.itemID);
}
@Override
public int hashCode() {
return Objects.hash(itemID);
}

2( 集合

因此更改自:

List<DiscoverItems> items = new ArrayList<>();

收件人:

Set<DiscoverItems> items = new HashSet<>();

当你需要在一个地方检查时,你可以转换:

List ---> Set ---> List

例如:

Set<DiscoverItems> set = new HashSet<>(items);
if (items.size() == set.size()) {
// No duplicates, use original list
} else {
// Duplicates removed, use new list
List<DiscoverItems> itemsWithoutDuplicates = new ArrayList<>(set);
}

或无附加条件:

Set<DiscoverItems> set = new HashSet<>(items);
List<DiscoverItems> itemsWithoutDuplicates = new ArrayList<>(set);

或者作为一个衬垫:

List<DiscoverItems> itemsWithoutDuplicates = new ArrayList<>(new HashSet<>(items));

提示

您应该将类命名为DiscoverItem,而不是DiscoverItems。因为它代表的是一个项目,而不是很多。

最新更新