2010-12-09 52 views
17

Conozco las diferencias entre Conjunto y Lista (únicas frente a duplicaciones permitidas, no ordenadas/ordenadas, etc.). Lo que estoy buscando es un conjunto que mantenga ordenados los elementos (eso es fácil), pero también necesito poder recuperar el índice en el que se insertó un elemento. Entonces, si inserto cuatro elementos, quiero saber el orden en que se insertó uno de ellos.Cómo obtener el índice de un elemento en java.util.Set

MySet<String> set = MySet<String>(); 
set.add("one"); 
set.add("two"); 
set.add("three"); 
set.add("four"); 

int index = set.getIndex("two"); 

Así que en un momento dado pueda comprobar si una cadena que ya se añadió, y obtener el índice de la cadena en el conjunto. ¿Hay algo como esto, o tengo que implementarlo yo mismo?

+0

¿Qué esperaría que getIndex devolviera si hubiera eliminado "uno" mientras tanto? –

+0

si no está en colecciones comunes http://commons.apache.org/collections/ entonces creo que tendrá que implementarlo usted mismo –

+0

Bueno, ya que el conjunto debe ser ordenado, si un elemento se elimina todos los elementos insertados después de eso se reasignaría una posición. Supongo que si hago un getIndex de un elemento que no existe, o que ha sido eliminado, obtendría un -1. –

Respuesta

11

Un pequeño método personalizado estático en una clase Util ayudaría:

public static int getIndex(Set<? extends Object> set, Object value) { 
    int result = 0; 
    for (Object entry:set) { 
    if (entry.equals(value)) return result; 
    result++; 
    } 
    return -1; 
} 

Si necesita/quiere una clase que es unaSet y ofrece un método getIndex(), sugiero fuertemente para implementar un nuevo Set y utilizar el patrón decorador:

public class IndexAwareSet<T> implements Set { 
    private Set<T> set; 
    public IndexAwareSet(Set<T> set) { 
    this.set = set; 
    } 

    // ... implement all methods from Set and delegate to the internal Set 

    public int getIndex(T entry) { 
    int result = 0; 
    for (T entry:set) { 
     if (entry.equals(value)) return result; 
     result++; 
    } 
    return -1; 
    } 
} 
+0

Gracias por el ejemplo. Una pregunta, ¿vale la pena llamar contiene (entrada T) antes de iterar a través del conjunto? –

+0

@Jose - depende del conjunto. HashSet: sí, contiene ejecuciones en O (1). TreeSet - no, ya que contiene necesidad de O (n) exactamente como el algoritmo 'getIndex'. Entonces tomaría el doble de tiempo. –

+0

Tenga en cuenta que si decora un HashSet, no obtendrá el comportamiento deseado (es decir, índice de acuerdo con el orden de inserción). Debe proporcionar un conjunto cuya orden de iteración coincida con el orden de inserción. LinkedHashSet es capaz de hacerlo. –

3

puede ampliar LinkedHashSet agregando su método getIndex() deseado. Son 15 minutos para implementarlo y probarlo. Simplemente vaya a través del conjunto utilizando el iterador y el contador, verifique la igualdad del objeto. Si lo encuentra, devuelva el contador.

+2

TreeSet no mantendrá el orden en que se agregaron los elementos, se ordenarán en su orden natural. –

+0

@Jose, gracias. editó la respuesta. –

12

Después de crear Conjunto simplemente convertirlo a la lista y obtener por el índice de la lista:

Set<String> stringsSet = new HashSet<>(); 
stringsSet.add("string1"); 
stringsSet.add("string2"); 

List<String> stringsList = new ArrayList<>(stringsSet); 
stringsList.get(0); // "string1"; 
stringsList.get(1); // "string2"; 
+0

Creo que la pregunta era cómo obtener el índice de un artículo en un conjunto y no cómo obtener un elemento por índice. – jbird

+2

stringsList.indexOf ("cadena1"); –

Cuestiones relacionadas