Java关联数组


214

如何像在PHP中那样在Java中创建和获取关联数组?

例如:

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

Answers:


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 2011年

9
如果您尝试访问不存在的密钥,PHP不会喜欢它,不:)
Svish

2
@edem,需要一些实现。但是,今天,由于性能差异,在几乎所有情况下都希望ArrayList使用。但这是另一个讨论。
JohanSjöberg,2012年

3
永远不要忘记初始化确切的哈希大小并将负载因子设置为1:HashMap <String,String>(capacity,1)。否则,您可能会实现巨大的开销,并且您的对象需要大量RAM。ArrayList +1,但是为什么不编辑答案?
马库斯

1
@Marcus“ 永远不要忘记初始化确切的哈希大小并将负载因子设置为1 ”-您从哪里得到建议?您几乎应该永远不要指定a的负载因子HashMap,并且一定要没有故意对行为进行基准测试并为您的用例找到更好的负载因子。指定初始大小的唯一原因是,如果您事先知道地图将非常大。HashMap如果为空,不会浪费(太多)内存,但是如果您打算创建一个大型地图,则可以通过预先指定其大小来保存多个数组调整大小。
dimo414 '16

47

Java没有像PHP那样的关联数组。

针对您的工作有多种解决方案,例如使用地图,但这取决于您要如何查找信息。您可以轻松地编写一个包含所有信息的类,并将其实例存储在中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有点尴尬,但很棒的解决方案。谢谢。
frostymarvelous 2012年

为什么使用List而不是ArrayList?这里是一个Java新手。
Sobiaholic 2015年

“列表”是一个抽象类,“数组列表”是该类的实现之一,还有从同一抽象类派生的其他类型的列表。因此,因此ArrayList也是一个List。您不能创建抽象类的实例,只能在此处使用它作为类型,您需要对实例使用实现。所以List是类型,而ArrayList是这里的实例。
veta

12

Java中没有关联数组之类的东西。它的最接近的亲戚是a 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所有其他答案似乎都假定“键”之一是整数。如果关联数组基于两个非整数键(我们将在python中说一个元组)怎么办?我相信您将需要使用这种方法,因为无法建立索引。
demongolem

10

查看Map接口和具体的类HashMap

要创建地图:

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

要添加键值对:

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

要检索与键关联的值:

assoc.get("name")

当然,您可以创建一个Maps数组,因为它似乎是您想要的:

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

Java中的关联数组,例如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);
}

更多信息,请参见Class SoftHashMap:https ://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html


Map.containsKey()方法迭代所有Map的键,因此Map.get()方法也是如此,当找到键时,该方法也自然返回一个值。因此,仅Map.get()仅执行一次这两种技术(因此性能更高),而无需编写此新代码。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,名称= prod1},{id = 0002,名称= prod2}]


1

在JDK 1.5(http://tinyurl.com/3m2lxju)中甚至有一个注释:“注意:此类已过时。新的实现应实现Map接口,而不是扩展此类。” 问候,北


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具有Perl / C世系。因此,有:未设置和不存在的变量,已设置但为NULL的值,布尔False值,以及标准语言所具有的所有其他内容。您必须分别测试它们,或者选择内置在函数/语法中的RIGHT评估。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.