Domanda

Da vari articoli online su Java 7 sono venuto a sapere che Java 7 sarà avere letterali di raccolta 1 come il seguente:

List<String> fruits = [ "Apple", "Mango", "Guava" ];
Set<String> flowers = { "Rose", "Daisy", "Chrysanthemum" };
Map<Integer, String> hindiNums = { 1 : "Ek", 2 : "Do", 3 : "Teen" }; 

Le mie domande sono:

  1. Non sarebbe stato possibile fornire un metodo statico of in tutte le classi di insiemi che potrebbero essere utilizzati come segue:

List<String> fruits = ArrayList.of("Apple", "Mango", "Guava");

IMO questo sembra buono come la versione letterale ed è anche abbastanza conciso. Perché allora hanno dovuto inventare una nuova sintassi ( EDIT:. Per 'nuovo' intendo 'una novità per Java')?

  1. Quando dico List<String> fruits = [ "Apple", "Mango", "Guava" ]; quello List avrei effettivamente ottenere? Sarebbe ArrayList o LinkedList o qualcos'altro?

1 Come notato nei commenti, letterali di raccolta fatto non fare il taglio per Java 7, né del resto Java 8. (Ecco un e-mail da Brian Goetz, uno sviluppatore di Oracle, che riassume il razionale per non apporre questa caratteristica,. e qui è la proposta stesso)

È stato utile?

Soluzione

Risposta alla domanda 2:

final List<Integer> piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9];

ti dà una immutabile .

L'intera idea di questa proposta che il sottotipo non può essere specificato. Il compilatore sceglie un idoneo attuazione seconda raccolta sul lato destro.

Leggi i dettagli qui: Proposta: Collection letterali

Risposta alla domanda 1: si avrebbe. E 'una questione di stile.

Altri suggerimenti

Un'altra cosa da notare è che per gli elenchi questo è molto facile usando args var, ma hanno un po 'pensare a come si farebbe per una mappa. Non c'è modo di fornire coppie di argomenti a un metodo var args, a meno che non si introduce un oggetto Map.Entry in più o qualcosa del genere.

Quindi, utilizzando la sintassi esistente che ci si finisce con

Map<String,String> map = HashMap.of( new Entry( "key1", "value1" ), 
                                     new Entry( "key2", "value2" ) );

che sarebbe ottenere molto faticoso molto rapidamente.

Anche se si va giù per il sentiero di utilizzare un builder (come noi), allora è abbastanza brutto

Map<String,String> map = CollectionUtil.<String,String>map()
                                        .put( "key1", "value1" )
                                        .put( "key2", "value2" )
                                        .map();

Non menzionato sopra è la semplicità di collezioni di collezioni. Diciamo che si desidera una costante per memorizzare i nomi di valuta e valori di diversi paesi.

// Currency devisions by country, and their various names
Map<String,Map<Float,List<String>>> CURRENCIES =
    { "US" : { 1 : ["dollar","buck"],
               0.25 : ["quarter"],
               0.10 : ["dime"],
               0.05 : ["nickel"],
               0.01 : ["penny"] },
      "UK" : { 1 : ["pound"],
               1.05 ["guinea"],
               0.125 : ["half crown"],
               0.05 : ["shilling","bob"],
               0.025 : ["sixpence"] } 
    };

Ho confezionare una quantità enorme di dati in dodici linee estremamente leggibili. Se avessi usato ArrayList.of (dieci volte) e alcuni simili mappa costruttore (quattro volte, con Map.EntryPair dieci!), Le chiamate di funzione avrebbero gonfiato il codice e ne ha fatto molto più difficile da leggere.

Mentre è definitivamente nel dominio di zucchero sintattico, questa è la caratteristica # 1 Non vedo l'ora di in Java 7 (se mai esce).

A1 Sì, è possibile, ma richiede di digitare sempre di più.

Anche se questo non è certamente qualcosa di essenzialmente sbagliato, è uno degli sviluppatori cose si lamentano di più. Loro (e qualche volta fanno la mia auto) sensazione che Java è troppo prolisso .

Per quanto l'hardware ancora più veloce, nuovi linguaggi di programmazione che all'inizio erano troppo costosi per eseguire calcoli è diventato fattibile, e sono ora utilizzati sempre di più e sono molto popolari. Quando gli sviluppatori devono scrivere in Java di nuovo si sentono, come oh no: , public static void main nuovo tipo di!.

Una delle cose che Java (tipologie e staticamente lingue in generale) ha dovuto aumentare la velocità di esecuzione è quello di eseguire il maggior numero di convalide possibile prima in esecuzione (che è, in fase di compilazione)

I nuovi linguaggi di programmazione (notevolmente Python e Ruby) fare una gioia per programma, perché si deve digitare meno per ottenere lo stesso.

La reazione di Java sta prendendo a questo, è quello di rendere il linguaggio più grande e incorporare alcune di queste "zucchero sintattico" nella lingua, ecco perché.

Anche linguaggi di programmazione come C # aveva queste caratteristiche estese (proprietà mi viene in mente) per rendere il codice dello sviluppatore meno.

Alla fine, penso che queste aggiunte beneficiano della lingua, ma devono essere aggiunti con molta attenzione, per evitare di rompere la compatibilità e / o creare un linguaggio che è così grande, che nessuno può usarlo.

Credo che in alternativa sarebbe stato per consentire i metodi di essere più espressiva nei loro nomi, ma che è molto complicato, per Java. Forse in una nuova lingua :).

La mappa messo firma del metodo avrebbe potuto essere in questo modo:

 /**
  * Analog to put( Object k, Object v );
  */
 public [( Object = k )]=( Object  v ) {
 } 

Quella consentono il nome del metodo sia: [(key)]=(value) e, infine, omettere la parentesi (come in Ruby o originariamente in Smalltalk) quindi questo metodo potrebbe essere:

 Map map = ....
 map.["name"]="Oscar";

Dal momento che non è possibile (perché []= non sono identificatori di metodo validi) e la scrittura:

 map.put("name","Oscar");

Is ... mmhh troppo prolisso, hanno deciso di aggiungere questa soluzione.

Un altro miglioramento sono letterali numerici, in modo da essere in grado di digitare:

 int million = 1_000_000;

A2 :. Otterrete qualcosa di diverso

A3 (in espansione il mio commento su kloffy risposta ).

Si potrebbe scrivere che lo stesso codice in Java a partire da oggi.

Stage, Scente, Group, Text, ImageView, Image accordata e le classi Java esistente, è possibile digitare:

 new Stage() {{
     title  =  "Group-Nodes-Transformation";
     scene  =  new Scene() {{
         width =  600;
         height = 600;
         content = new Group() {{
             content = new Object[] =  {
                 new Circle() {{
                     centerX = 300;
                     centerY = 300;
                     radius = 250;
                     fill = Color.WHITE;
                     stroke = Color.BLACK;
                 }},
                 new Text() {{
                     x = 300;
                     y = 300;
                     content = "Mr. Duke";
                 }},
                 new ImageView() {{
                     image = new  Image() {{
                         url = "D:\\TEST\\Documents\\duke.png"
                         width = 50;
                         height = 50;
                     }};
                 }};
             };
         }};
     }};
 }};

Potrebbero sono stati ispirati allo stile di programmazione dichiarativa di JavaFX . Se questo è il caso, tuttavia, sono deluso che non vanno tutto il modo per letterali oggetto sostegno pure. Ecco un esempio di letterali oggetto in JavaFX:

Stage {
    title: "Group-Nodes-Transformation"
    scene: Scene {
        width: 600
        height: 600
        content: Group {
            content: [
                Circle {
                    centerX: 300
                    centerY: 300
                    radius: 250
                    fill: Color.WHITE
                    stroke: Color.BLACK
                },
                Text {
                    x: 300
                    y: 300
                    content: "Mr. Duke"
                },
                ImageView {
                    image: Image {
                        url: "D:\\TEST\\Documents\\duke.png"
                        width:50
                        height:50
                    }
                }
            ]
        }
    }
}

Credo che questo stile di programmazione certamente si presta ad alcune aree di applicazione. Alla fine è sempre una questione di gusto ...

progettazione La lingua è una questione di gusti. Detto questo, questo tipo di inizializzazione lista / oggetto è diventato molto popolare. Ad esempio, C # è quasi la stessa cosa. La sintassi è abbastanza flessibile e, come anche i vostri esempi, consente di inizializzare qualcosa come una linea dizionario. Ho un po 'come la sintassi i progettisti hanno scelto qui.

IMO questo è solo un sintattica zucchero che semplifica il codice un po '. Perché non sorpreso da uno zucchero dello stesso tipo:

int []arr1 = new int[] {1,2,3};
int []arr2 = {1,2,3};

E 'solo un modo conveniente per esprimere una semplice idea invece di scrivere qualcosa di simile

int []arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;

Fa questo aggiungere qualcosa di veramente nuovo alla nostra vita? Beh no. Lo fa rende la vita un po 'più facile? Credo, sì.

Per quanto riguarda la seconda parte della domanda, non so cosa sarebbe tipi effettivi. Ma francamente, come spesso si cura di ciò che di implementazione della raccolta è? Soprattutto tenendo conto che tali raccolte dovrebbero essere relativamente piccolo (con tutti i valori digitati da uno sviluppatore). In ogni caso, in quei rari casi in cui si fa la cura, proprio non usare questa sintassi semplificata e fare il lavoro da soli.

Non è del tutto nuova sintassi come tali letterali sono presenti in Python, Javascript (JSON) e probabilmente altre lingue.

Non ho visto alcuna informazione su Java 7 ma ad essere sinceri (sono stati focalizzata su C ++ e Javascript ultimamente), ma in realtà è bello vedere una tale aggiunta alla lingua.

Giusto per chiarire un punto -. Non hanno "inventato nuova sintassi"

Io non sono sicuro al 100%, dove l'idea originale è venuto da, ma utilizzando "[]" per indicare le liste e "{}" per indicare le mappe esiste in Perl (dove quelli sono utilizzati nella costruzione di refs array e hash arbitri) .

Non c'è "set" in perl in senso stretto, ma il più implementazione idiomatica di un insieme è un (membro Mappa del set a 1) mappa, in modo da "{}" anche adatta.

Quindi, Perl avrebbe detto esattamente le stesse cose che avete elencato come:

$fruits = [ "Apple", "Mango", "Guava" ]; # Creates array reference
$flowers = { "Rose" => 1, "Daisy" => 1, "Chrysanthemum" => 1 };
     # or { map {$_=>1} ("Rose", "Daisy", "Chrysanthemum"))
$hindiNums = { 1 => "Ek", 2 => "Do", 3 => "Teen" }; 

Non sto dicendo che quanto sopra è venuto da Perl, ovviamente, ma è coerente con almeno un'altra lingua e quindi, eventualmente, con un più ampio utilizzo.

Hai ragione questo è solo zucchero sintattico vuota.

Anche il tuo ArrayList.of(...) sarebbe solo di breve portata di mano per new ArrayList<...>(Arrays.asList(...))

Credo che una delle ragioni è che of( ... ) genererà un incontrollato di avviso se si tenta di popolarlo con le istanze di oggetti generici.

Il motivo, si espande ... ad una matrice java e java array non piace istanze generici.

Ecco un esempio dalla specifica che si occupa di questo tema specifico:

List<List<Integer>> pascalsTriangle =
    [[1],
     [1, 1],
     [1, 2, 1],
     [1, 3, 3, 1],
     [1, 4, 6, 4, 1]]

Non v'è attualmente alcun modo per inizializzare questa variabile in questo modo conciso e senza incontrollato di avvertimento.

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