Tableau associatif Java

214

Comment puis-je créer et récupérer des tableaux associatifs en Java comme je le peux en PHP?

Par exemple:

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

Réponses:

356

Java ne prend pas en charge les tableaux associatifs, mais cela pourrait facilement être réalisé en utilisant a Map. Par exemple,

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

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

Encore plus précis dans votre exemple (puisque vous pouvez remplacer String par n'importe quel objet qui répond à vos besoins) serait de déclarer:

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

Voir la documentation officielle pour plus d'informations

Johan Sjöberg
la source
2
Cela lancera NullPointerExceptionsi la carte externe ne contient pas de carte pour l'entrée 0. PHP n'est-il pas plus permissif avec $ arr [0] ['nom'] (je ne connais pas du tout ce langage)?
Tomasz Nurkiewicz
9
PHP ne l'aimerait pas si vous tentiez d'accéder à une clé qui n'existe pas, non :)
Svish
2
@edem, une mise en œuvre était nécessaire. Aujourd'hui, cependant, je préférerais ArrayListdans presque tous les cas en raison de différences de performances (inattendues?). Mais c'est une autre discussion.
Johan Sjöberg
3
N'oubliez jamais d'initialiser la taille de hachage exacte et de définir le facteur de charge sur 1: HashMap <String, String> (capacité, 1). Sinon, vous pouvez implémenter une énorme surcharge et vos objets ont besoin de beaucoup de RAM. +1 pour ArrayList, mais pourquoi aucune modification de la réponse?
Marcus
1
@Marcus " N'oubliez jamais d'initialiser la taille de hachage exacte et de définir le facteur de charge sur 1 " - où obtenez-vous ce conseil? Vous ne devriez presque jamais spécifier le facteur de charge d'un HashMap, et certainement pas sans comparer intentionnellement le comportement et trouver un meilleur facteur de charge pour votre cas d'utilisation. La seule raison de spécifier une taille initiale est si vous savez à l'avance que la carte sera très grande. HashMapne gaspille pas (beaucoup) de mémoire s'il est vide, mais si vous avez l'intention de créer une grande carte, vous pouvez enregistrer plusieurs redimensionnements de tableau en spécifiant sa taille à l'avance.
dimo414
47

Java n'a pas de tableaux associatifs comme PHP.

Il existe différentes solutions pour ce que vous faites, comme l'utilisation d'une carte, mais cela dépend de la façon dont vous souhaitez rechercher les informations. Vous pouvez facilement écrire une classe contenant toutes vos informations et en stocker des instances dans un fichier ArrayList.

public class Foo{
    public String name, fname;

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

Puis...

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

Vous pouvez donc y accéder comme ...

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

Vous pouvez accomplir cela via Maps. Quelque chose comme

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

Mais lorsque vous commencez à utiliser Java, je suis sûr que vous constaterez que si vous créez une classe / un modèle qui représente vos données, ce seront vos meilleures options. je ferais

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
la source
Je pense que j'aime mieux cette méthode merci. Venir de php où tout est si simple est un peu gênant avec java, mais c'est une excellente solution. Merci.
frostymarvelous
Pourquoi utiliser List au lieu d'ArrayList? un débutant java ici.
Sobiaholic
'List' est une classe abstraite et 'ArrayList' est l'une des implémentations de cette classe, il existe d'autres types de listes dérivées de la même classe abstraite. Donc, à cause de cela, un ArrayList est également une liste. Vous ne pouvez pas créer une instance d'une classe abstraite, utilisez-la simplement comme type ici, vous devez utiliser l'implémentation pour vos instances. Ainsi, la liste est le type et ArrayList est l'instance ici.
veta
12

Il n'y a pas de tableau associatif en Java. Son parent le plus proche est a Map, qui est fortement typé, mais a une syntaxe / API moins élégante.

C'est le plus proche que vous pouvez obtenir en fonction de votre exemple:

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
la source
1
Quelle est la LazyMap.decorateet InstantiateFactoryet tout ça pour?
Svish
+1 Toutes les autres réponses semblent supposer que l'une des "clés" est un entier. Et si le tableau associé était basé sur deux clés non entières (un tuple que nous dirions en python)? Je pense que vous devrez utiliser cette approche car l'indexation devient impossible.
demongolem
10

Regardez l' interface Map et la classe concrète HashMap .

Pour créer une carte:

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

Pour ajouter une paire valeur / clé:

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

Pour récupérer la valeur associée à une clé:

assoc.get("name")

Et bien sûr, vous pouvez créer un tableau de cartes, car cela semble être ce que vous voulez:

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

Eh bien, j'étais également à la recherche d'un tableau associatif et j'ai trouvé la liste des cartes comme la meilleure solution.

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

}


}
alchimiste
la source
5

Java n'a pas de tableaux associatifs, la chose la plus proche que vous pouvez obtenir est l' interface Map

Voici un exemple de cette page.

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

Si exécuté avec:

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

Tu auras:

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

Tableaux associatifs en Java comme en 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);
}

Plus d'informations, voir Class SoftHashMap: https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html

abahet
la source
La méthode Map.containsKey () parcourt toutes les clés de la carte, tout comme la méthode Map.get () qui renvoie également naturellement une valeur lorsque la clé est trouvée. Donc, juste Map.get () exécute ces deux techniques, une seule fois (donc plus performant), sans écrire ce nouveau code. Map.get () renvoie également la valeur associée à la première clé correspondante, puis arrête la recherche, ce qui est plus rapide et le comportement familier pour ce modèle. Le code dans cet article continue à parcourir toutes les clés même après la correspondance de la clé de recherche et renvoie la dernière clé correspondante (et non la première clé correspondante).
Matthew
3

Utilisez ArrayList <Map <String, String>>

Voici un exemple de code:

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

Production :

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

abahet
la source
1

Dans JDK 1.5 (http://tinyurl.com/3m2lxju), il y a même une note: "REMARQUE: cette classe est obsolète. Les nouvelles implémentations devraient implémenter l'interface Map, plutôt que d'étendre cette classe." Cordialement, N.

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

Oui, cela nécessite une itération pour rechercher la valeur par clé, mais si vous en avez besoin, ce sera le meilleur choix.

msangel
la source
0

En y réfléchissant davantage, je voudrais jeter les tuples comme un moyen plus général de résoudre ce problème. Bien que les tuples ne soient pas natifs de Java, j'utilise des Javatuples pour me fournir la même fonctionnalité qui existerait dans d'autres langues. Un exemple de la façon de traiter la question posée est

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

J'aime cette approche car elle peut être étendue à des triplets et à d'autres groupements d'ordre supérieur avec des classes et des méthodes fournies par l'API.

demongolem
la source
-2

Concernant le commentaire de PHP «Non, PHP ne l'aimerait pas». En fait, PHP continuerait à chugging à moins que vous ne définissiez des niveaux d'exception / erreur très restrictifs (pour PHP), (et peut-être même pas à ce moment-là).

Ce qui arrivera par défaut, c'est qu'un accès à un élément de tableau variable / hors limites 'désactive' la valeur que vous attribuez. NON, ce n'est PAS nul. PHP a une lignée Perl / C, d'après ce que je comprends. Il y a donc: des variables non définies et non existantes, des valeurs qui SONT définies mais sont NULL, des valeurs booléennes fausses, puis tout le reste des langages standard. Vous devez tester ces éléments séparément, OU choisir l'évaluation DROITE intégrée à la fonction / syntaxe.

Dennis
la source