Perché il metodo removeRange () di Java AbstractList è protetto?


98

Qualcuno ha qualche idea, perché il metodo removeRange in AbstractList (e anche in ArrayList ) è protected? Sembra un'operazione abbastanza ben definita e utile, ma comunque, per usarla, siamo costretti a sottoclassare l'implementazione di List.

C'è qualche logica nascosta? Mi sembra abbastanza inspiegabile.

Risposte:


163

Sì, perché non è così che rimuovi un intervallo dal codice esterno. Invece, fai questo:

list.subList(start, end).clear();

Questo in realtà chiama removeRangedietro le quinte.


L'OP chiede perché removeRangenon fa parte Listdell'API pubblica. Il motivo è descritto nell'articolo 40 di Effective Java 2nd ed, e lo cito qui:

Esistono tre tecniche per accorciare elenchi di parametri eccessivamente lunghi. Uno consiste nel suddividere il metodo in più metodi, ognuno dei quali richiede solo un sottoinsieme dei parametri. Se fatto con noncuranza, questo può portare a troppi metodi, ma può anche aiutare a ridurre il conteggio dei metodi aumentando l'ortogonalità. Ad esempio, considera l' java.util.Listinterfaccia. Non fornisce metodi per trovare il primo o l'ultimo indice di un elemento in una sottolista, entrambi i quali richiederebbero tre parametri. Fornisce invece il subListmetodo, che accetta due parametri e restituisce una visualizzazione di una sottolista. Questo metodo può essere combinato con i metodi indexOfo lastIndexOf, ognuno dei quali ha un singolo parametro, per ottenere la funzionalità desiderata. Inoltre, ilsubListIl metodo può essere combinato con qualsiasi metodo che opera su Listun'istanza per eseguire calcoli arbitrari sulle sottoliste. L'API risultante ha un rapporto peso / potenza molto elevato.

Si può sostenere che removeRangenon ha molti parametri e quindi probabilmente non è un candidato per questo trattamento, ma dato che esiste un modo per invocare removeRangetramite il subList, non c'è motivo di ingombrare l' Listinterfaccia con un metodo ridondante.


La AbstractList.removeRangedocumentazione dice:

Questo metodo viene chiamato cleardall'operazione su questo elenco e sui suoi elenchi secondari. L'override di questo metodo per sfruttare gli elementi interni dell'implementazione dell'elenco può migliorare sostanzialmente le prestazioni cleardell'operazione su questo elenco e sui suoi elenchi secondari.

Inoltre, vedere l'implementazione di OpenJDK di AbstractList.cleare SubList.removeRange.


9
Ok, si può fare in questo modo, ma perché ? Sembra imbarazzante. I singoli elementi possono essere rimossi direttamente dall'elenco, perché allora non più elementi?
Joonas Pulakka

1
@Joonas: Item 40 of Effective Java, 2nd ed descrive la logica di questo. Incollerò la sezione pertinente nel caso non abbiate il libro.
Chris Jester-Young,

21
+1 (risposta alla domanda). Tuttavia, solo perché viene fornita una motivazione non significa che abbia senso. Il processo di abbreviazione degli elenchi di parametri ostacola la capacità degli sviluppatori di comprendere le operazioni disponibili in un'API, il che va direttamente contro il motivo per cui gli elenchi sono stati accorciati in primo luogo.
Sam Harwell,

3
Così tipico per java. Rendiamolo più complicato e meno efficace.
Tomáš Zato - Ripristina Monica il

2
come nota a margine, hai notato che removeRangechiama arraycopyinutilmente quando la ArrayListversione viene utilizzata su un intervallo che si estende fino alla fine dell'elenco? hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/...~~V~~3rd l' numMovedè 0, quindi l'intero codice arraycopy potrebbe essere stato messo in un unico if(come fatto in remove); la differenza è che a) arraycopy è una chiamata nativo, incorrere in un sovraccarico, b) arraycopy non sempre controlla params correttezza stackoverflow.com/questions/12594046/...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.