Java assoziatives Array

214

Wie kann ich assoziative Arrays in Java wie in PHP erstellen und abrufen?

Beispielsweise:

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

Antworten:

356

Java unterstützt keine assoziativen Arrays, dies könnte jedoch leicht mit a erreicht werden Map. Z.B,

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

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

Noch genauer für Ihr Beispiel (da Sie String durch jedes Objekt ersetzen können, das Ihren Anforderungen entspricht) wäre die Deklaration von:

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

Weitere Informationen finden Sie in der offiziellen Dokumentation

Johan Sjöberg
quelle
2
Dies wird ausgelöst, NullPointerExceptionwenn die äußere Karte keine Karte für den Eintrag enthält 0. Ist PHP mit $ arr [0] ['name'] nicht freizügiger (ich kenne diese Sprache überhaupt nicht)?
Tomasz Nurkiewicz
9
PHP würde es nicht mögen, wenn Sie versuchen würden, auf einen Schlüssel zuzugreifen, der nicht existiert, nein :)
Svish
2
@edem, einige Implementierung war notwendig. Heute aber ich würde es vorziehen , in ArrayListfast allen Fällen wegen (unerwartet?) Leistungsunterschiede. Aber das ist eine andere Diskussion.
Johan Sjöberg
3
Vergessen Sie niemals, die genaue Hash-Größe zu initialisieren und den Ladefaktor auf 1 zu setzen: HashMap <String, String> (Kapazität, 1). Andernfalls können Sie einen enormen Overhead implementieren und Ihre Objekte benötigen zu viel RAM. +1 für ArrayList, aber warum keine Bearbeitung der Antwort?
Marcus
1
@Marcus " Vergessen Sie niemals, die genaue Hash-Größe zu initialisieren und den Ladefaktor auf 1 zu setzen " - woher erhalten Sie diesen Rat? Sie sollten fast nie den Lastfaktor von a angeben HashMap, und schon gar nicht, ohne das Verhalten absichtlich zu bewerten und einen besseren Lastfaktor für Ihren Anwendungsfall zu finden. Der einzige Grund, eine Anfangsgröße anzugeben, besteht darin, dass Sie im Voraus wissen, dass die Karte sehr groß sein wird. HashMapVerschwenden Sie nicht (viel) Speicher, wenn Sie leer sind. Wenn Sie jedoch eine große Karte erstellen möchten, können Sie mehrere Array-Größen speichern, indem Sie die Größe im Voraus angeben.
dimo414
47

Java hat keine assoziativen Arrays wie PHP.

Es gibt verschiedene Lösungen für Ihre Aktivitäten, z. B. die Verwendung einer Karte. Dies hängt jedoch davon ab, wie Sie die Informationen nachschlagen möchten. Sie können einfach eine Klasse schreiben, die alle Ihre Informationen enthält, und Instanzen davon in einer speichern ArrayList.

public class Foo{
    public String name, fname;

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

Und dann...

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

So können Sie darauf zugreifen wie ...

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

Sie können dies über Karten erreichen. Etwas wie

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

Aber wenn Sie anfangen, Java zu verwenden, werden Sie sicher feststellen, dass das Erstellen einer Klasse / eines Modells, das Ihre Daten darstellt, die besten Optionen sind. Ich würde es tun

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);
Amir Raminfar
quelle
Ich denke, ich mag diese Methode besser, danke. Von PHP zu kommen, wo alles so einfach ist, ist mit Java etwas umständlich, aber eine großartige Lösung. Vielen Dank.
frostymarvelous
Warum List anstelle von ArrayList verwenden? ein Java-Neuling hier.
Sobiaholic
'List' ist eine abstrakte Klasse und 'ArrayList' ist eine der Implementierungen dieser Klasse. Es gibt andere Arten von Listen, die von derselben abstrakten Klasse abgeleitet sind. Aus diesem Grund ist eine ArrayList auch eine Liste. Sie können keine Instanz einer abstrakten Klasse erstellen. Verwenden Sie sie hier als Typ. Sie müssen die Implementierung für Ihre Instanzen verwenden. Die Liste ist also der Typ, und ArrayList ist hier die Instanz.
Veta
12

In Java gibt es kein assoziatives Array. Sein nächster Verwandter ist a Map, der stark typisiert ist, jedoch eine weniger elegante Syntax / API aufweist.

Dies ist der nächste Punkt, den Sie anhand Ihres Beispiels erreichen können:

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
Tomasz Nurkiewicz
quelle
1
Was ist das LazyMap.decorateund InstantiateFactoryund Sachen für?
Svish
+1 Alle anderen Antworten scheinen davon auszugehen, dass einer der "Schlüssel" eine Ganzzahl ist. Was wäre, wenn das zugehörige Array auf zwei nicht ganzzahligen Schlüsseln basieren würde (ein Tupel, das wir in Python sagen würden)? Ich glaube, Sie müssten diesen Ansatz verwenden, da eine Indizierung unmöglich wird.
Demongolem
10

Schauen Sie sich die Map- Oberfläche und die konkrete Klasse HashMap an .

So erstellen Sie eine Karte:

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

So fügen Sie ein Schlüssel-Wert-Paar hinzu:

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

So rufen Sie den einem Schlüssel zugeordneten Wert ab:

assoc.get("name")

Und natürlich können Sie eine Reihe von Karten erstellen, wie es scheint, was Sie wollen:

Map<String, String>[] assoc = ...
ChrisJ
quelle
6

Nun, ich war auch auf der Suche nach einem assoziativen Array und fand die Liste der Karten als die beste Lösung.

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);

}


}
Alchimist
quelle
5

Java hat keine assoziativen Arrays. Das nächste, was Sie bekommen können, ist die Map-Oberfläche

Hier ist ein Beispiel von dieser Seite.

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);
    }
}

Wenn ausgeführt mit:

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

Du wirst kriegen:

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

Assoziative Arrays in Java wie 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);
}

Weitere Informationen finden Sie unter Class SoftHashMap: https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html

abahet
quelle
Die Map.containsKey () -Methode durchläuft alle Schlüssel der Map, ebenso wie die Map.get () -Methode, die natürlich auch einen Wert zurückgibt, wenn der Schlüssel gefunden wird. Nur Map.get () führt diese beiden Techniken nur einmal aus (also performanter), ohne diesen neuen Code zu schreiben. Außerdem gibt Map.get () den Wert zurück, der dem ersten übereinstimmenden Schlüssel zugeordnet ist, und beendet dann die Suche. Dies ist schneller und das bekannte Verhalten für dieses Muster. Der Code in diesem Beitrag durchläuft weiterhin alle Schlüssel, auch nachdem der Suchschlüssel abgeglichen wurde, und gibt den zuletzt übereinstimmenden Schlüssel zurück (nicht den ersten übereinstimmenden Schlüssel).
Matthew
3

Verwenden Sie ArrayList <Map <String, String >>

Hier ein Codebeispiel:

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);

Ausgabe :

Produkte: [{id = 0001, name = prod1}, {id = 0002, name = prod2}]

abahet
quelle
1

In JDK 1.5 (http://tinyurl.com/3m2lxju) gibt es sogar einen Hinweis: "HINWEIS: Diese Klasse ist veraltet. Neue Implementierungen sollten die Map-Schnittstelle implementieren, anstatt diese Klasse zu erweitern." Grüße, N.

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

Ja, dies erfordert eine Iteration, um den Wert nach Schlüssel zu ermitteln. Wenn Sie jedoch alle benötigen, ist dies die beste Wahl.

msangel
quelle
0

Wenn ich mehr darüber nachdenke, möchte ich Tupel wegwerfen, um dieses Problem allgemeiner zu lösen. Während Tupel nicht in Java beheimatet sind, verwende ich Javatuples , um mir die gleiche Funktionalität bereitzustellen, die in anderen Sprachen vorhanden wäre. Ein Beispiel für den Umgang mit der gestellten Frage ist

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

Ich mag diesen Ansatz, weil er mit API-bereitgestellten Klassen und Methoden auf Tripel und andere Gruppierungen höherer Ordnung erweitert werden kann.

Demongolem
quelle
-2

In Bezug auf den PHP-Kommentar "Nein, PHP würde es nicht mögen". Tatsächlich würde PHP weiter tuckern, es sei denn, Sie legen einige sehr restriktive (für PHP) Ausnahme- / Fehlerstufen fest (und vielleicht auch dann nicht).

Was standardmäßig passiert, ist, dass ein Zugriff auf eine nicht vorhandene Variable / ein außerhalb der Grenzen liegendes Array-Element Ihren Wert, den Sie zuweisen, "deaktiviert". NEIN, das ist NICHT null. Nach meinem Verständnis hat PHP eine Perl / C-Linie. Es gibt also: nicht gesetzte und nicht vorhandene Variablen, Werte, die gesetzt sind, aber NULL sind, Boolesche Falschwerte, dann alles andere, was Standardsprachen haben. Sie müssen diese separat testen ODER die in Funktion / Syntax integrierte RECHTE Bewertung auswählen.

Dennis
quelle