Java連想配列


214

PHPでできるように、Javaで連想配列を作成してフェッチするにはどうすればよいですか?

例えば:

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

回答:


356

Javaは連想配列をサポートしていませんが、これはを使用して簡単に実現できますMap。例えば、

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

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

(Stringをニーズを満たす任意のオブジェクトに置き換えることができるため)この例ではさらに正確に、次のように宣言します。

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

詳細については、公式ドキュメントを参照してください


2
これはNullPointerException、外部マップにエントリのマップが含まれていない場合にスローされます0。$ arr [0] ['name']を使用すると、PHPの方が許容度が高くなりますか(この言語はまったくわかりません)。
Tomasz Nurkiewicz

9
PHPは、存在しないキーにアクセスしようとした場合、それを
望ま

2
@edem、いくつかの実装が必要でした。ただし、今日では、(予期しない?)パフォーマンスの違いのため、ほとんどすべてのケースでが好みArrayListます。しかし、それは別の議論です。
JohanSjöberg、2012

3
正確なハッシュサイズを初期化し、負荷係数を1に設定することを忘れないでください:HashMap <String、String>(capacity、1)。そうしないと、大きなオーバーヘッドが実装され、オブジェクトに多くのRAMが必要になります。ArrayListの+1、しかし答えの編集がないのはなぜですか?
マーカス

1
@Marcus " 正確なハッシュサイズを初期化し、負荷係数を1に設定することを忘れないでください -どこでそのアドバイスを受けますか?あなたは、ほぼべきでないの負荷係数を指定しないHashMap意図的行動をベンチマーキングして、ユースケースのためのより良い負荷率を見つけることなく、確かではありません。初期サイズを指定する唯一の理由は、マップが非常に大きくなることが事前にわかっている場合です。HashMap空の場合でも(多くの)メモリを無駄にすることはありませんが、大きなマップを作成する場合は、事前にサイズを指定することで、いくつかの配列のサイズ変更を保存できます。
dimo414

47

Javaには、PHPのように連想配列はありません。

Mapの使用など、現在行っていることにはさまざまな解決策がありますが、情報をどのように検索するかによって異なります。すべての情報を保持するクラスを簡単に記述し、それらのインスタンスをに保存できますArrayList

public class Foo{
    public String name, fname;

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

その後...

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

だからあなたはそれらにアクセスすることができます...

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

20

これはマップを介して実行できます。何かのようなもの

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

しかし、Javaの使用を開始すると、データを表すクラス/モデルを作成するのが最良のオプションであることがわかります。私はするだろう

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

おかげでこの方法の方が好きだと思います。すべてが非常にシンプルなphpから来るのは、javaを使用するのはちょっと厄介ですが、優れたソリューションです。ありがとう。
凍るような素晴らしい

ArrayListではなくListを使用する理由 ここではJava初心者。
ソビアホリック2015年

「List」は抽象クラスであり、「ArrayList」はそのクラスの実装の1つです。同じ抽象クラスから派生した他のタイプのリストがあります。このため、ArrayListもListです。抽象クラスのインスタンスを作成することはできません。ここでタイプとして使用するだけで、インスタンスの実装を使用する必要があります。したがって、リストはタイプであり、ここではArrayListがインスタンスです。
ヴェタ

12

Javaには連想配列のようなものはありません。最も近いものはでありMap、厳密に型指定されていますが、構文/ APIはエレガントではありません。

これはあなたの例に基づいてあなたが得ることができる最も近いものです:

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
LazyMap.decorateInstantiateFactoryし、もののため?
Svish

+1他のすべての回答は、「キー」の1つが整数であると想定しているようです。関連付けられた配列が2つの非整数キー(Pythonで言うタプル)に基づいている場合はどうなりますか?索引付けが不可能になると、このアプローチを使用する必要があると思います。
デーモンゴレム2012

10

Mapインターフェースと具象クラスHashMapを見てください。

マップを作成するには:

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

Key-Valueペアを追加するには:

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

キーに関連付けられた値を取得するには:

assoc.get("name")

そして、確かに、あなたが望んでいるように見えるので、マップの配列を作成することができます:

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

6

まあ私も連想配列を探していて、マップのリストが最良の解決策であることがわかりました。

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には連想配列がありません。入手できる最も近いものはMapインターフェースです。

これがそのページのサンプルです。

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

で実行する場合:

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

あなたは得るでしょう:

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

3

PHPのようなJavaの連想配列:

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

詳細については、クラスSoftHashMapを参照してください:https ://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html


Map.containsKey()メソッドはすべてのMapのキーを反復処理します。また、キーが見つかると自然に値を返すMap.get()メソッドも反復処理します。つまり、Map.get()は、この新しいコードを記述せずに、両方の手法を1回だけ実行する(パフォーマンスが向上する)だけです。また、Map.get()は、最初に一致したキーに関連付けられた値を返し、検索を停止します。これは、このパターンの動作が速く、使い慣れた動作です。この投稿のコードは、検索キーが一致した後でもすべてのキーを繰り返し処理し、最後に一致したキー(最初に一致したキーではない)を返します。
マシュー

3

ArrayList <Map <String、String>>を使用

ここにコードサンプル:

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

出力:

製品:[{id = 0001、name = prod1}、{id = 0002、name = prod2}]


1

JDK 1.5(http://tinyurl.com/3m2lxju)には、「注:このクラスは廃止されました。新しい実装では、このクラスを拡張するのではなく、Mapインターフェースを実装する必要があります。」という注記さえあります。よろしく、N.


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

はい、これはキーで値を検索するための反復が必要ですが、それらすべてが必要な場合は、これが最良の選択です。



0

もっとよく考えて、この問題に対処するためのより汎用的な方法としてタプルを捨てたいと思います。タプルは、Javaにネイティブではありませんが、私が使用しJavatuplesを私に他の言語に存在するのと同じ機能を提供します。尋ねられた質問に対処する方法の例は

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

このアプローチが好きなのは、APIが提供するクラスとメソッドを使用して、トリプルやその他の高次のグループに拡張できるためです。


-2

PHPのコメントについて、「いいえ、PHPは気に入らないでしょう」。実際、PHPが非常に制限的な(PHPの)例外/エラーレベルを設定しない限り(そして、それでもそうでない場合でも)、PHPは問題を続けます。

デフォルトで発生することは、存在しない変数/境界外配列要素へのアクセスが、割り当てている値を「設定解除」することです。いいえ、それはnullではありません。PHPにはPerl / Cの系統があります。つまり、設定されていない変数と存在しない変数、設定されているがNULLである値、ブール値のFalse値、そして標準言語が持つ他のすべてがあります。これらを個別にテストするか、組み込みの関数/構文で適切な評価を選択する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.