Android:SortedList与重复

理解RecyclerViewSortedList有一些问题。

比方说,我有一个非常简单的类只有一个非常简单的类持有数据:

 public class Pojo { public final int id; public final char aChar; public Pojo(int id, char aChar) { this.id = id; this.aChar = aChar; } @Override public String toString() { return "Pojo[" + "id=" + id + ",aChar=" + aChar + "]"; } } 

我的理解是,sorting列表将不会包含任何重复。

但是当我有一个SortedList这样的callback:

 .... @Override public boolean areContentsTheSame(Pojo oldItem, Pojo newItem) { return oldItem.aChar == newItem.aChar; } @Override public int compare(Pojo o1, Pojo o2) { return Character.compare(o1.aChar, o2.aChar); } @Override public boolean areItemsTheSame(Pojo item1, Pojo item2) { return item1.id == item2.id; } 

当我添加具有相同的id,但不同的字符的多个项目时,我结束了重复。

 sortedList.add(new Pojo(1, 'a')); sortedList.add(new Pojo(1, 'b')); 

我希望列表更新该项目。 相反,现在我有多个项目,即使areItemsTheSame返回true

Solutions Collecting From Web of "Android:SortedList与重复"

SortedList不保留任何通过id映射(因为API中没有id)。 所以,当sorting标准改变(在你的情况下a到b),SortedList无法find现有的元素。

你可以保持自己的id映射,然后你的add方法如下:

 void add(Item t) { Item existing = idMap.get(t.id); if (existing == null) { sortedList.add(t); } else { sortedList.updateItemAt(sortedList.indexOf(existing), t); } idMap.put(t.id, t); } 

你还需要实现一个remove方法来从idMap中删除这个项目。

正如Minhtdh在他的回答中已经提到的,问题在于你的compare()

请参阅add() ,通过使用您实现的compare()来查找现有对象的索引。 因此,当您的compare()返回0以外的值时,它将该对象添加到列表中。

比较内容之前,您需要检查项目是否相同。 但是,如果您的内容可以相同,则需要进行二级比较。

这就是我将如何在你的情况下实现compare()

 @Override public int compare(Pojo o1, Pojo o2) { int result; if (areItemsTheSame(o1, o2) { result = 0; } else { result = Character.compare(o1.aChar, o2.aChar); if (result == 0) { // TODO implement a secondary comparison } } return result; } 

我认为你应该使用Integer.compare(o1.id, o2.id);compare方法中,SortList决定这两个项目是否相同。

您可以通过执行此操作来检查对象是否已经存在于sorting列表中。

 if (sortedList.indexOf(item) == -1) { sortedList.add(item); //Item still does not exist because index is -1 } else { sortedList.updateItemAt(sortedList.indexOf(item), item); } 

在Java中,不包含重复元素的集合是Set 。 常见的实现类是HashSet和TreeSet 。 你错了,假定SortedList是这样做的。