JavaRush /Java Blog /Random-IT /Inizializzazione della doppia parentesi graffa
Joysi
Livello 41

Inizializzazione della doppia parentesi graffa

Pubblicato nel gruppo Random-IT

1. Inizializzazione della doppia parentesi graffa

L'inizializzazione tramite doppie parentesi graffe ( di seguito denominata Inizializzazione delle doppie parentesi graffe ) è uno strumento Java per la creazione di raccolte come list, set e map contemporaneamente alla loro dichiarazione.
Inizializzazione della doppia graffa - 1
Quando sono necessari elenchi con elementi fissi, ad esempio un elenco di prodotti o valute supportati, la dichiarazione dell'elenco contemporaneamente alla sua inizializzazione migliora la leggibilità del codice. Questo è il motivo per cui l'inizializzazione con doppia parentesi graffa sta guadagnando popolarità, poiché non esistono altri metodi standard per creare raccolte con inizializzazione simultanea nel codice. Sfortunatamente, a differenza di altri linguaggi di programmazione, Java non supporta raccolte di valori letterali. A causa di questa limitazione, la creazione di una lista immodificabile con anche un numero limitato di elementi ci costringe a scrivere molte righe di codice sotto forma di chiamate ripetute add()per aggiungere gli elementi desiderati con il ritorno a capo finale:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Si tratta di una descrizione inutilmente ridondante che potrebbe essere semplificata. Compiliamo gli elenchi statici nel modo per noi conveniente, ovvero direttamente nei blocchi statici durante l'inizializzazione, che è ciò in cui Double bracel'inizializzazione ci aiuterà, permettendoci di scrivere tutto in una riga:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
Allo stesso modo, Double bracel'inizializzazione ci aiuterà a inserire valori e HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
Sembra tutto così elegante, ma ha i suoi svantaggi, che rendono l'inizializzazione del Double brace un anti-pattern. Li esamineremo più approfonditamente nel prossimo capitolo.

Pro e contro dell'inizializzazione della doppia graffa.

Doublel'inizializzazione delle parentesi graffe utilizza la creazione di una classe interna anonima . Ciò che inizialmente è nascosto in superficie, tuttavia, Double bracel'inizializzazione crea una classe con un'ulteriore inizializzazione della sua istanza ogni volta che la si utilizza. Inoltre viene utilizzato un riferimento nascosto a questa classe privata, che può portare a possibili perdite di memoria. Inoltre, non è possibile utilizzare l'operatore fantasma per i generici (operatore diamante < >), poiché non possiamo accedere all'interno di una classe anonima.
(Dal traduttore: Ancora una volta più in dettaglio:
dopo la prima {viene creata una classe anonima interna, dopo la seconda {l'inizializzazione avviene quando si crea un'istanza della classe, in cui abbiamo accesso ai campi e ai metodi della classe esterna ( relativo alla classe anonima).)
Professionisti:
  1. Ridurre le righe nel codice
  2. Creazione e inizializzazione in un'unica espressione.
Aspetti negativi:
  1. Creare una classe anonima nascosta a te.
  2. Il che ci costa costi aggiuntivi per la sua istanza ogni volta che la utilizziamo.
  3. Ogni volta che viene creato un riferimento nascosto ad esso, il che può portare a perdite di memoria.
Verdetto: A causa degli svantaggi di cui sopra e dell'esistenza di alternative alla doppia graffa, l'inizializzazione è considerata un anti-pattern nel mondo Java. Salva il gattino

Alternative all'inizializzazione della doppia graffa in Java

La buona notizia è che esistono altri modi per raggiungere gli stessi obiettivi in ​​Java. Possiamo implementare in una riga di codice la creazione e l'inizializzazione di un ArrayList utilizzando il costruttore Copy della classe Collection come mostrato di seguito:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()ci restituirà un elenco di lunghezza fissa passato al ArrayListcostruttore della copia. Tieni presente la differenza tra gli elenchi a lunghezza fissa restituiti da Arrays.asList()e Collections.unmodifiableList(): non puoi aggiungere o rimuovere elementi ArrayListdi - , ma puoi modificare un elemento per indice utilizzando set(), cosa che non puoi fare con un elenco restituito da Collections.unmodifiableList(). Se vuoi ottenere un piccolo elenco, questo è il modo migliore, anche se sarà meno trasparente per Setle altre raccolte, quindi dovrai crearlo Listprima di creare Set-a. Ma questo è comunque meglio dell'inizializzazione con doppia parentesi graffa, poiché in questo caso non viene creata una classe anonima interna aggiuntiva ogni volta che viene utilizzata. Se stai utilizzando Java 8 hai un altro metodo alternativo. L'API JDK 8 Stream ti aiuterà a creare piccole raccolte combinando Stream Factoryi metodi di output in una raccolta List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
Perché Setpuoi utilizzare Collectors.toSet()il metodo invece Collectors.toList()come di seguito:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
A proposito, Stream collecti metodi non garantiscono che le raccolte che generano siano protette dalle modifiche. In Java 8, le raccolte restituite (come - ArrayList, HashSet, e HashMap) sono abbastanza comuni (possiamo modificarle), ma questo fatto potrebbe essere corretto nelle future versioni di JDK. Per ora è tutto sull'inizializzazione Double bracein Java. Questo modello è accettabile per test e demo, ma non abbastanza buono per l'uso in produzione. A causa dei suoi svantaggi intrinseci, l'inizializzazione del doppio rinforzo è diventata oggigiorno un anti-modello, soprattutto considerando le alternative disponibili. Io stesso utilizzo ancora questa costruzione per inizializzare mappe statiche e basta. Perché Listpreferisco creare Collectionscombinando con la creazione Array.asListnel suo costruttore. E se utilizzo Java 8, un progetto che utilizza l'API Stream e collect(). Articoli correlati: se ti è piaciuto questo tutorial e desideri saperne di più sui modelli, i principi e le migliori pratiche di programmazione Java, potresti voler consultare anche gli altri articoli sul nostro sito . Lettura consigliata: se vuoi saperne di più sui modelli e sulle migliori pratiche dovresti leggere Programmazione efficace di Joshua Bloch , nessun libro può prendere il suo posto. E se sei già esperto in Java e stai cercando un libro sui design pattern, il cui stile di presentazione umoristico sia interessante e di facile lettura, presta attenzione a “Head First. Modelli di progettazione" .
Dal traduttore: ho volutamente fornito un collegamento al libro originale di Bloch, poiché la sua traduzione in russo non ha avuto successo (ad esempio, Builder = costruttore).
Traduzione dell'articolo Che cos'è l'inizializzazione di Double Brace in Java? Esempio di Anti Pattern (pubblicato nell'ottobre 2015).
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION