Java asosiatif-array

214

Bagaimana saya bisa membuat dan mengambil array asosiatif di Jawa seperti saya bisa di PHP?

Sebagai contoh:

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

Jawaban:

356

Java tidak mendukung array asosiatif, namun ini dapat dengan mudah dicapai menggunakan a Map. Misalnya,

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

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

Bahkan lebih akurat untuk contoh Anda (karena Anda dapat mengganti String dengan objek apa pun yang memenuhi kebutuhan Anda) akan menyatakan:

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

Lihat dokumentasi resmi untuk informasi lebih lanjut

Johan Sjöberg
sumber
2
Ini akan melempar NullPointerExceptionjika peta luar tidak berisi peta untuk masuk 0. Bukankah PHP lebih permisif dengan $ arr [0] ['name'] (Saya tidak tahu bahasa ini sama sekali)?
Tomasz Nurkiewicz
9
PHP tidak akan suka jika Anda mencoba mengakses kunci yang tidak ada, tidak :)
Svish
2
@edem, beberapa implementasi diperlukan. Namun hari ini , saya lebih suka ArrayListdalam hampir semua kasus karena perbedaan kinerja (tak terduga?). Tapi itu diskusi lain.
Johan Sjöberg
3
Jangan pernah lupa menginisialisasi ukuran hash yang tepat dan mengatur load factor sebagai 1: HashMap <String, String> (kapasitas, 1). Kalau tidak, Anda dapat menerapkan overhead besar dan objek Anda perlu banyak RAM. +1 untuk ArrayList, tetapi mengapa tidak ada edit jawaban?
Marcus
1
@ Marscus " Jangan pernah lupa menginisialisasi ukuran hash yang tepat dan mengatur load factor sebagai 1 " - di mana Anda mendapatkan saran itu? Anda seharusnya hampir tidak pernah menentukan faktor beban dari HashMap, dan tentu saja tidak tanpa sengaja membandingkan perilaku dan menemukan faktor beban yang lebih baik untuk kasus penggunaan Anda. Satu-satunya alasan untuk menentukan ukuran awal adalah jika Anda tahu sebelumnya bahwa peta akan sangat besar. HashMaptidak menyia-nyiakan (banyak) memori jika kosong, tetapi jika Anda berniat untuk membuat peta besar, Anda dapat menyimpan beberapa ukuran array dengan menentukan ukurannya di depan.
dimo414
47

Java tidak memiliki array asosiatif seperti PHP.

Ada berbagai solusi untuk apa yang Anda lakukan, seperti menggunakan Peta, tetapi itu tergantung pada bagaimana Anda ingin mencari informasi. Anda dapat dengan mudah menulis kelas yang menyimpan semua informasi Anda dan menyimpan instance mereka dalam sebuah ArrayList.

public class Foo{
    public String name, fname;

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

Lalu...

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

Jadi Anda dapat mengaksesnya seperti ...

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

Anda dapat melakukannya melalui Maps. Sesuatu seperti

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

Tetapi ketika Anda mulai menggunakan Java saya yakin Anda akan menemukan bahwa jika Anda membuat kelas / model yang mewakili data Anda akan menjadi pilihan terbaik Anda. Saya akan lakukan

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
sumber
Saya rasa saya suka metode ini lebih baik, terima kasih. Datang dari php di mana semuanya sangat sederhana adalah semacam canggung menggunakan java, tetapi solusi yang bagus. Terima kasih.
dingin
Mengapa menggunakan List, bukan ArrayList? seorang pemula java di sini.
Sobiaholic
'Daftar' adalah kelas abstrak dan 'ArrayList' adalah salah satu implementasi dari kelas itu, ada jenis daftar lain yang berasal dari kelas abstrak yang sama. Jadi karena ini ArrayList juga Daftar. Anda tidak dapat membuat turunan dari kelas abstrak, cukup gunakan itu sebagai tipe di sini, Anda perlu menggunakan implementasi untuk instance Anda. Jadi Daftar adalah tipenya, dan ArrayList adalah contoh di sini.
veta
12

Tidak ada yang namanya array asosiatif di Jawa. Kerabat terdekatnya adalah aMap , yang diketik dengan kuat, namun memiliki sintaks / API yang kurang elegan.

Ini adalah yang terdekat yang bisa Anda dapatkan berdasarkan contoh Anda:

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
sumber
1
Apa LazyMap.decoratedan InstantiateFactorydan hal-hal untuk?
Svish
+1 Semua jawaban lain tampaknya menganggap bahwa salah satu "kunci" adalah bilangan bulat. Bagaimana jika array associate didasarkan pada dua kunci non-integer (tuple yang akan kita katakan dengan python)? Saya percaya Anda harus menggunakan pendekatan ini karena pengindeksan menjadi tidak mungkin.
demongolem
10

Lihatlah antarmuka Peta , dan pada kelas konkret HashMap .

Untuk membuat Peta:

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

Untuk menambahkan pasangan nilai kunci:

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

Untuk mengambil nilai yang terkait dengan kunci:

assoc.get("name")

Dan tentu saja, Anda dapat membuat array dari Maps, seperti yang Anda inginkan:

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

Yah saya juga sedang mencari array Asosiatif dan menemukan Daftar peta sebagai solusi terbaik.

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

}


}
ahli alkimia
sumber
5

Java tidak memiliki array asosiatif, hal terdekat yang bisa Anda dapatkan adalah antarmuka Peta

Ini contoh dari halaman itu.

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

Jika dijalankan dengan:

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

Anda akan mendapatkan:

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

Array asosiatif di Jawa seperti di 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);
}

Info lebih lanjut, lihat Kelas SoftHashMap: https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html

abahet
sumber
Metode Map.containsKey () berulang melalui semua kunci Peta, dan begitu juga metode Map.get () yang juga secara alami mengembalikan nilai ketika kunci ditemukan. Jadi, hanya Map.get () melakukan kedua teknik itu, hanya sekali (jadi lebih banyak pemain), tanpa menulis kode baru ini. Map.get () juga mengembalikan nilai yang terkait dengan kunci pertama yang cocok, dan kemudian berhenti mencari, yang lebih cepat dan perilaku yang sudah dikenal untuk pola ini. Kode dalam posting ini terus mengulangi semua kunci bahkan setelah kunci pencarian cocok, dan mengembalikan kunci yang cocok terakhir (bukan kunci yang cocok pertama).
Matius
3

Gunakan ArrayList <Map <String, String>>

Di sini contoh kode:

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

Output:

produk: [{id = 0001, nama = prod1}, {id = 0002, nama = prod2}]

abahet
sumber
1

Di JDK 1.5 (http://tinyurl.com/3m2lxju) bahkan ada catatan: "CATATAN: Kelas ini sudah usang. Implementasi baru harus mengimplementasikan antarmuka Peta, daripada memperluas kelas ini." Salam, N.

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

Ya, ini membutuhkan iterasi untuk mencari nilai dengan kunci, tetapi jika Anda membutuhkan semuanya, ini akan menjadi pilihan terbaik.

msangel
sumber
0

Berpikir lebih banyak tentang itu, saya ingin membuang tupel sebagai cara yang lebih umum untuk menangani masalah ini. Meskipun tupel bukan asli Java, saya menggunakan Javatuples untuk memberi saya fungsionalitas yang sama yang akan ada dalam bahasa lain. Contoh cara menangani pertanyaan yang diajukan adalah

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

Saya suka pendekatan ini karena dapat diperluas hingga tiga kali lipat dan pengelompokan lebih tinggi dengan api menyediakan kelas dan metode.

demongolem
sumber
-2

Mengenai komentar PHP 'Tidak, PHP tidak akan menyukainya'. Sebenarnya, PHP akan terus chugging kecuali Anda menetapkan beberapa tingkat pengecualian / kesalahan yang sangat terbatas (untuk PHP), (dan mungkin bahkan tidak saat itu).

Apa yang AKAN terjadi secara default adalah bahwa akses ke elemen array yang tidak ada / di luar batas 'membatalkan' nilai yang Anda tetapkan. TIDAK, itu BUKAN nol. PHP memiliki garis keturunan Perl / C, dari apa yang saya mengerti. Jadi ada: variabel tidak disetel dan tidak ada, nilai-nilai yang diatur tetapi NULL, nilai-nilai Boolean False, maka segala sesuatu yang lain yang memiliki bahasa standar. Anda harus menguji mereka secara terpisah, ATAU memilih fungsi / sintaks bawaan evaluasi KANAN.

Dennis
sumber