Contiene AllAll () e retainAll () nella cardinalità dell'indirizzo dell'interfaccia Collection?

StackOverflow https://stackoverflow.com/questions/816379

  •  03-07-2019
  •  | 
  •  

Domanda

In Java, contiene Poiché tutte le raccolte Java nella libreria standard estendono AbstractCollection, si presume che funzionino tutte allo stesso modo.

Tuttavia, la documentazione di questi metodi nell'interfaccia Collection non dice nulla. Si suppone che si possa dedurre da AbstractCollection o questo non è stato specificato in modo specifico per consentire di definire raccolte che funzionano in modo diverso?

Ad esempio, Bag in apache-collections afferma esplicitamente che rispetta la cardinalità e afferma che viola il contratto della versione di Collection (anche se in realtà non lo fa).

Quindi, quali sono le semantiche di queste operazioni in Collection piuttosto che in AbstractCollection?

Modifica: Coloro che si stanno chiedendo perché mi piacerebbe, è perché come parte del mio dottorato. lavoro Ho dimostrato che gli sviluppatori non si aspettano la violazione della conformità in Apache, ma sto cercando di capire perché l'interfaccia Collection è stata lasciata così ambigua.

È stato utile?

Soluzione

I javadocs per IncludesAll (nella raccolta) dicono:

  

Restituisce: vero se questa raccolta   contiene tutti gli elementi nel file   raccolta specificata

e per retainAll (nella raccolta):

  

Conserva solo gli elementi in questo   raccolta contenuta nel file   raccolta specificata (facoltativo   funzionamento). In altre parole, rimuove   da questa collezione tutto suo   elementi che non sono contenuti in   raccolta specificata.

Ho letto il contratto contieneAll per indicare che chiamare a.containsAll (b) restituirà true, se e solo se, chiamando a.contains (bElem) per ogni elemento bElem in b restituirà true. Vorrei anche implicare che a.containsAll (someEmptyCollection) restituirebbe anche true. Mentre dichiari i javadocs per AbstractCollection, lo dichiari in modo più esplicito:

  

Questa implementazione scorre sul   raccolta specificata, controllando ciascuno   elemento restituito dall'iteratore in   girare per vedere se è contenuto in questo   collezione. Se tutti gli elementi sono così   contenuto true viene restituito, altrimenti   falso.

Sono d'accordo che il contatto per la raccolta di contiene Tutti dovrebbe essere più esplicito per evitare qualsiasi possibilità di confusione. (E che la lettura dei javadocs per AbstractCollection NON avrebbe dovuto essere necessaria per confermare la comprensione della Collezione)

Non avrei ipotizzato il numero di elementi duplicati dopo una chiamata a keepAll. Il contratto dichiarato in Collection (secondo la mia lettura) non implica in alcun modo come sarebbero gestiti i duplicati in entrambe le raccolte. Sulla base della mia lettura di retainAll in collection, sono possibili tutti i possibili risultati di a.retainAll (b):

  1. il risultato contiene 1 di ogni elemento che ha almeno una copia in a e b
  2. il risultato contiene ogni elemento (inclusi i duplicati) che era in a, tranne quelli che non sono in b
  3. o anche, il risultato contiene da qualche parte tra 1 e il numero di copie trovate in a di ciascun elemento in a, ad eccezione di quelle non in b. Mi sarei aspettato il n. 1 o il n. 2, ma presumo che uno qualsiasi dei tre sia legale in base al contratto.

I javadocs per AbstractCollection confermano che utilizza # 2:

  

Questa implementazione scorre su questo   raccolta, controllando ogni elemento   restituito dall'iteratore a sua volta a   vedere se è contenuto nel specificato   collezione. Se non è così contenuto,   viene rimosso da questa raccolta con   il metodo di rimozione dell'iteratore

Anche se dal momento che questo non è nella mia lettura del contratto dell'interfaccia Collection originale, non assumerei necessariamente che il comportamento di Collection sia generalmente in questo modo.

Forse dovresti considerare di inviare gli aggiornamenti suggeriti a JavaDoc una volta terminato.

Per quanto riguarda "perché l'interfaccia Collection è stata lasciata così ambigua" - dubito seriamente che sia stata fatta intenzionalmente - probabilmente solo qualcosa a cui non è stata data la dovuta priorità durante la scrittura di quella parte delle API.

Altri suggerimenti

Non credo che Collection lo definisca in questo modo o nell'altro, ma è diventato semplicemente una sorta di convenzione seguire il comportamento di AbstractCollection, ad esempio google-collections do: vedi la loro documentazione Multiset (Multiset è ciò che chiamano Bag)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top