我创建了一个应用程序,显示我附近的用户项目。
我使用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
。因为它代表的是一个项目,而不是很多。