Android: SortedList con duplicados

Tengo algunos problemas de comprensión de RecyclerView s SortedList .

Digamos que tengo una clase muy simple que solo tiene una clase muy simple que contiene datos:

 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 + "]"; } } 

Entiendo que la lista ordenada no contendrá duplicados.

Pero cuando tengo un SortedList con callbacks como este:

 .... @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; } 

Termino con duplicados cuando agrego varios elementos con el mismo id pero diferentes caracteres.

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

Esperaría que la lista actualizara el elemento. Ahora tengo varios elementos aunque areItemsTheSame devuelve true .

SortedList no mantiene ningún mapeo por ids (porque no hay ids en la API). Por lo tanto, cuando los criterios de clasificación cambian (a a b en su caso), SortedList no puede encontrar el elemento existente.

Usted puede guardar el mapa de identificación usted mismo, entonces tiene su método de agregar como sigue:

 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); } 

También necesitará implementar un método remove para quitar el elemento del idMap.

Como Minhtdh ya mencionó en su respuesta, el problema está dentro de su compare() .

Vea, add() busca el índice del objeto existente usando el método compare() que implementa. Por lo tanto, cuando su compare() devuelve algo distinto de 0, agrega el objeto a la lista.

Usted necesitaría comprobar si los artículos son iguales antes de comparar su contenido. Sin embargo, si su contenido puede ser el mismo que se necesita una comparación secundaria.

Así es como implementaría la compare() en su caso:

 @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; } 

Creo que deberías usar Integer.compare(o1.id, o2.id); En el método de compare , es donde SortList decide que esos 2 elementos son iguales o no.

En Java, una colección que no contiene elementos duplicados es Set . Las clases comunes de implementación son HashSet y TreeSet . Usted está equivocado asumiendo que SortedList hace eso.

  • GapWorker con vistas desechadas o adjuntas no se puede reciclar. IsScrap: false isAttached: true
  • Cómo utilizar RecyclerView y CardView
  • ¿Por qué RecyclerView onBindViewHolder se llama una sola vez?
  • Vista del reciclador que muestra un solo elemento
  • Cómo agregar el recyclerview al proyecto
  • ¿Es posible hacer que CursorAdapter se establezca en recycleview, al igual que ListView?
  • Android: error de "intentar utilizar un mapa de bits reciclado" con Bitmaps temporales
  • android RecyclerView setOnScrollChangeListener necesita api 23?
  • Android: No se puede resolver el método 'findFirstVisibleItemPosition ()'?
  • Ejemplo sencillo de Android RecyclerView
  • Actualizar los contenidos de recyclerview fallan en la hoja inferior
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.