Java associative-array


214

Come posso creare e recuperare array associativi in ​​Java come posso fare in PHP?

Per esempio:

$arr[0]['name'] = 'demo';
$arr[0]['fname'] = 'fdemo';
$arr[1]['name'] = 'test';
$arr[1]['fname'] = 'fname';

Risposte:


356

Java non supporta array associativi, tuttavia questo potrebbe essere facilmente ottenuto usando a Map. Per esempio,

Map<String, String> map = new HashMap<String, String>();
map.put("name", "demo");
map.put("fname", "fdemo");
// etc

map.get("name"); // returns "demo"

Ancora più preciso al tuo esempio (dato che puoi sostituire String con qualsiasi oggetto che soddisfi le tue esigenze) sarebbe dichiarare:

List<Map<String, String>> data = new ArrayList<>();
data.add(0, map);
data.get(0).get("name"); 

Vedere la documentazione ufficiale per ulteriori informazioni


2
Questo genererà NullPointerExceptionse la mappa esterna non contiene la mappa per l'ingresso 0. PHP non è più permissivo con $ arr [0] ['name'] (non conosco affatto questa lingua)?
Tomasz Nurkiewicz,

9
A PHP non piacerebbe se provassi ad accedere a una chiave che non esiste, no :)
Svish,

2
@edem, era necessaria qualche implementazione. Oggi però, io preferirei ArrayListin quasi tutti i casi, a causa di imprevisti (?) Differenze di prestazioni. Ma questa è un'altra discussione.
Johan Sjöberg,

3
Non dimenticare di inizializzare la dimensione esatta dell'hash e impostare il fattore di carico su 1: HashMap <String, String> (capacità, 1). Altrimenti puoi implementare un enorme sovraccarico e i tuoi oggetti hanno bisogno di molta RAM. +1 per ArrayList, ma perché non modificare la risposta?
Marcus,

1
@Marcus " Non dimenticare mai di inizializzare la dimensione esatta dell'hash e impostare il fattore di carico su 1 " - dove ricevi questo consiglio? Non dovresti quasi mai specificare il fattore di carico di a HashMap, e certamente non senza fare un benchmark intenzionale del comportamento e trovare un fattore di carico migliore per il tuo caso d'uso. L'unico motivo per specificare una dimensione iniziale è se sai in anticipo che la mappa sarà molto grande. HashMapnon spreca (molta) memoria se vuota, ma se si intende creare una mappa di grandi dimensioni è possibile salvare diversi ridimensionamenti di array specificando le dimensioni in primo piano.
dimo414,

47

Java non ha array associativi come PHP.

Esistono varie soluzioni per ciò che stai facendo, come l'utilizzo di una mappa, ma dipende da come desideri cercare le informazioni. Puoi facilmente scrivere una classe che contiene tutte le tue informazioni e archiviarne istanze in un ArrayList.

public class Foo{
    public String name, fname;

    public Foo(String name, String fname){
        this.name = name;
        this.fname = fname;
    }
}

E poi...

List<Foo> foos = new ArrayList<Foo>();
foos.add(new Foo("demo","fdemo"));
foos.add(new Foo("test","fname"));

Quindi puoi accedervi come ...

foos.get(0).name;
=> "demo"

20

Puoi farlo tramite Maps. Qualcosa di simile a

Map<String, String>[] arr = new HashMap<String, String>[2]();
arr[0].put("name", "demo");

Ma quando inizi a usare Java, sono sicuro che scoprirai che se crei una classe / modello che rappresenti i tuoi dati saranno le tue migliori opzioni. farei

class Person{
String name;
String fname;
}
List<Person> people = new ArrayList<Person>();
Person p = new Person();
p.name = "demo";
p.fname = "fdemo";
people.add(p);

Penso che mi piace meglio questo metodo, grazie. Arrivare da php dove tutto è così semplice è un po 'imbarazzante usare java, ma un'ottima soluzione. Grazie.
gelido

Perché usare List invece di ArrayList? un novizio java qui.
Sobiaholic

'Elenco' è una classe astratta e 'ArrayList' è una delle implementazioni di quella classe, ci sono altri tipi di liste derivate dalla stessa classe astratta. Per questo motivo un ArrayList è anche un elenco. Non puoi creare un'istanza di una classe astratta, usala come tipo qui, devi usare l'implementazione per le tue istanze. Quindi l'Elenco è il tipo e ArrayList è l'istanza qui.
veta,

12

Non esiste un array associativo in Java. Il suo parente più vicino è a Map, che è fortemente tipizzato, ma ha una sintassi / API meno elegante.

Questo è il più vicino che puoi ottenere in base al tuo esempio:

Map<Integer, Map<String, String>> arr = 
    org.apache.commons.collections.map.LazyMap.decorate(
         new HashMap(), new InstantiateFactory(HashMap.class));

//$arr[0]['name'] = 'demo';
arr.get(0).put("name", "demo");

System.out.println(arr.get(0).get("name"));
System.out.println(arr.get(1).get("name"));    //yields null

1
Qual è la LazyMap.decoratee InstantiateFactorye roba per?
Svish,

+1 Tutte le altre risposte sembrano supporre che una delle "chiavi" sia un numero intero. E se l'array associato fosse basato su due chiavi non intere (una tupla che diremmo in Python)? Credo che dovresti utilizzare questo approccio poiché l'indicizzazione diventa impossibile.
demongolem,

10

Guarda l' interfaccia della mappa e la classe concreta HashMap .

Per creare una mappa:

Map<String, String> assoc = new HashMap<String, String>();

Per aggiungere una coppia chiave-valore:

assoc.put("name", "demo");

Per recuperare il valore associato a una chiave:

assoc.get("name")

E sicuramente, puoi creare una serie di mappe, poiché sembra essere quello che vuoi:

Map<String, String>[] assoc = ...

6

Beh, ero anche alla ricerca di array associativi e ho trovato l'elenco delle mappe come la migliore soluzione.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class testHashes {

public static void main(String args[]){
    Map<String,String> myMap1 = new HashMap<String, String>();

    List<Map<String , String>> myMap  = new ArrayList<Map<String,String>>();

    myMap1.put("URL", "Val0");
    myMap1.put("CRC", "Vla1");
    myMap1.put("SIZE", "Vla2");
    myMap1.put("PROGRESS", "Vla2");

    myMap.add(0,myMap1);
    myMap.add(1,myMap1);

    for (Map<String, String> map : myMap) {
        System.out.println(map.get("URL"));
    }

    //System.out.println(myMap);

}


}


5

Java non ha array associativi, la cosa più vicina che puoi ottenere è l' interfaccia della mappa

Ecco un esempio da quella pagina.

import java.util.*;

public class Freq {
    public static void main(String[] args) {
        Map<String, Integer> m = new HashMap<String, Integer>();

        // Initialize frequency table from command line
        for (String a : args) {
            Integer freq = m.get(a);
            m.put(a, (freq == null) ? 1 : freq + 1);
        }

        System.out.println(m.size() + " distinct words:");
        System.out.println(m);
    }
}

Se eseguito con:

java Freq if it is to be it is up to me to delegate

Otterrai:

8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}

3

Matrici associative in Java come in PHP:

SlotMap hmap = new SlotHashMap();
String key = "k01";
String value = "123456";
// Add key value
hmap.put( key, value );

// check if key exists key value
if ( hmap.containsKey(key)) {
    //.....        
}

// loop over hmap
Set mapkeys =  hmap.keySet();
for ( Iterator iterator = mapkeys.iterator(); iterator.hasNext();) {
  String key = (String) iterator.next();
  String value = hmap.get(key);
}

Maggiori informazioni, vedi Class SoftHashMap: https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html


Il metodo Map.containsKey () scorre tutte le chiavi della mappa, così come il metodo Map.get () che restituisce naturalmente anche un valore quando viene trovata la chiave. Quindi solo Map.get () esegue entrambe queste tecniche, solo una volta (quindi più performante), senza scrivere questo nuovo codice. Inoltre Map.get () restituisce il valore associato alla prima chiave corrispondente, quindi interrompe la ricerca, il che è più veloce e il comportamento familiare per questo modello. Il codice in questo post continua a scorrere tutte le chiavi anche dopo la corrispondenza della chiave di ricerca e restituisce l'ultima chiave corrispondente (non la prima chiave corrispondente).
Matteo,

3

Usa ArrayList <Mappa <String, String>>

Ecco un esempio di codice:

ArrayList<Map<String, String>> products = new ArrayList<Map<String, String>>();
while (iterator.hasNext()) {
         Map<String, String> product = new HashMap<String, String>();
         Element currentProduct = iterator.next();
         product.put("id",currentProduct.get("id"));
         product.put("name" , currentProduct.get("name") );
         products.add(product );
}
System.out.println("products : " + products);

Produzione :

prodotti: [{id = 0001, nome = prod1}, {id = 0002, nome = prod2}]


1

In JDK 1.5 (http://tinyurl.com/3m2lxju) c'è anche una nota: "NOTA: questa classe è obsoleta. Le nuove implementazioni dovrebbero implementare l'interfaccia Map, piuttosto che estenderla." Saluti, N.


1
Object[][] data = {
{"mykey1", "myval1"},
{"mykey2", "myval2"},
{new Date(), new Integer(1)},
};

Sì, questo richiede l'iterazione per la ricerca del valore per chiave, ma se hai bisogno di tutti, questa sarà la scelta migliore.



0

Pensandoci di più, vorrei scartare le tuple come un modo più generico di affrontare questo problema. Mentre le tuple non sono native di Java, io uso Javatuples per fornirmi la stessa funzionalità che esisterebbe in altre lingue. Un esempio di come affrontare la domanda posta è

Map<Pair<Integer, String>, String> arr = new HashMap<Pair<Integer, String>, String>();
Pair p1 = new Pair(0, "name");
arr.put(p1, "demo");

Mi piace questo approccio perché può essere esteso a triple e altri raggruppamenti di ordine superiore con classi e metodi forniti da api.


-2

Per quanto riguarda il commento di PHP "No, a PHP non piacerebbe". In realtà, PHP continuerebbe a soffocare a meno che non imposti dei livelli di eccezione / errore molto restrittivi (per PHP), (e forse nemmeno allora).

Ciò che accadrà per impostazione predefinita è che un accesso a una variabile non esistente / fuori dall'elemento dell'array "disinserisce" il valore a cui si sta assegnando. NO, NON è null. PHP ha un lignaggio Perl / C, da quello che ho capito. Quindi ci sono: variabili non impostate e inesistenti, valori che SONO impostati ma sono NULL, valori falsi booleani, quindi tutto il resto dei linguaggi standard. Devi testare quelli separatamente, OPPURE scegli la valutazione DESTRA integrata nella funzione / sintassi.

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.