En Java, ¿por qué (no clasificado) Set implementa Iterable, pero SortedMap no?

7

Hay dos aspectos de esta pregunta que sentí que estaban demasiado relacionados como para hacer preguntas separadas.

  1. ¿Por qué no SortedMap implementa Iterable<Map.Entry<K,V>> ?

Si necesita realizar una acción en cada par clave-valor en un mapa, la iteración sobre el entrySet () parece ser el camino a seguir. Entonces, ¿por qué no proporcionar un método de iterador directo () en SortedMap? A menos que esté preocupado de que la orden de iteración sea inconsistente en un HashMap. Lo que me lleva a:

  1. ¿Implementar Iterable implica un ordenamiento estable?

Iterar sobre una colección ordenada (List, SortedMap, SortedSet) es una excelente manera de implementar de manera confiable equals () (ver Nota 1) y hacer otras cosas que tienen que producir el mismo resultado cada vez. Iterar sobre un conjunto o mapa sin clasificar puede dar lugar a un orden diferente si lo llama varias veces, por lo que no es adecuado para estos fines. Especialmente si estás comparando HashSets o HashMaps, dos de ellos podrían contener los mismos objetos, pero el orden de sus iteradores sería diferente.

Supongo que hay dos aspectos de esas preguntas:

  1. ¿Cuáles son las razones históricas de estas decisiones de diseño?

  2. Si vuelve a hacerlo hoy, ¿hay respuestas correctas a estas preguntas? ¿Tal vez OrderedIterable debería extender Iterable para garantizar el pedido?

Notas :

  1. Originalmente sugerí que necesitabas un pedido confiable para implementar hashCode (), pero si sumas todos los hashcodes, resulta que no necesitas un pedido confiable si tu algoritmo hash es conmutativo. La adición se usa comúnmente para los códigos hash y es conmutativa: a + b = b + ay B. Incluso con desbordamiento, la adición sigue siendo conmutativa, de modo que a + Integer.MAX_VALUE = Integer.MAX_VALUE + a. Todavía necesita un pedido confiable para implementar equals () para poder comparar el primer elemento de uno con el primer elemento del otro, etc.

P.S.

Esta pregunta es sobre las interfaces Iterable , Set , SortedSet , Map y SortedMap . Está bien mostrar otras interfaces como ejemplos, pero No creo que la interfaz Collection sea relevante para esta pregunta. Es peculiar y tiene el potencial de ser una distracción.

    
pregunta GlenPeterson 04.06.2015 - 15:59

1 respuesta

11

Aunque desde un punto de vista técnico es correcto decir que Set implementa Iterable , pero SortedMap no lo hace, no es una pregunta muy útil. Una pregunta más útil es si ambas clases ofrecen la interfaz Iterable , y ciertamente ambas lo hacen.

Como usted sabe, hay tres formas de ofrecer una interfaz:

  1. Implementándolo explícitamente usando la palabra clave implements .
  2. Al implementar una interfaz que extiende la interfaz en cuestión.
  3. Al exponer una función que devuelve la interfaz en cuestión.

Set se declara de la siguiente manera: public interface Set<E> extends Collection<E> {... así que, como puede ver, Set no implementa directamente Iterable , solo lo implementa de manera indirecta, en virtud de implementar Collection , que se extiende Iterable .

Ahora, SortedMap también implementaría Iterable indirectamente, al igual que Set , si implementara Collection , pero ni siquiera hace eso. En su lugar, expone una función entrySet() , que devuelve un Collection , que extiende Iterable .

Por lo tanto, puedes tener tu muy deseado Iterable en ambos casos.

Si desea insistir en la pregunta técnica de por qué Set (indirectamente) implementa Iterable , pero SortedMap lo ofrece a través de una función, la respuesta es que los diseñadores del tiempo de ejecución en lenguaje java hicieron La decisión hace mucho tiempo de abstenerse de hacer un uso extensivo de las interfaces que se extienden a otras interfaces. Es por eso que Map<K,V> no extiende Collection<Map.Entry<K,V>> , ofreciendo un método entrySet() en su lugar.

Podrían haber hecho lo contrario, y de hecho, los diseñadores del tiempo de ejecución del lenguaje C # eligieron ir por el otro lado, por lo que IDictionary<K,V> extiende ICollection<KeyValuePair<K,V>> .

He experimentado con ambas formas y todavía no he llegado a una decisión concluyente sobre cuál es la mejor. Simplemente parecen ser dos formas diferentes de lograr lo mismo.

La implementación de Iterator no implica un ordenamiento estable, como parece entender (y, por lo tanto, no tengo claro dónde se encuentra su pregunta al respecto). Puede repetir un mapa sin clasificar, en cuyo caso nadie puede decir cuál será el orden de los elementos, y puede insertar un elemento en el mapa y repetirlo, en cuyo caso el orden de los elementos puede ser completamente diferente del tiempo anterior. (No solo diferentes por un elemento: puede parecer que todos los elementos se han reorganizado).

No hay necesidad de una interfaz OrderedIterable porque su firma sería idéntica a Iterable . (Y no me refiero a la elección de la gente java para introducir un Set además de Collection ). Puede simplemente invocar OrderedMap.entrySet() , que la documentación promete devolverá un pedido conjunto, lo que significa que el Iterator de ese conjunto siempre producirá artículos en orden.

    
respondido por el Mike Nakis 04.06.2015 - 16:13

Lea otras preguntas en las etiquetas