PHP中是否有Java HashMap等效?

new*_*bie 65 php hashmap

我需要类似于Java中的HashMap的PHP对象,但是当我用Google搜索时我没有找到,所以如果有人知道我如何在PHP中模仿HashMaps,那么将非常感谢帮助.

sus*_*ani 80

PHP中的数组可以具有键值结构.

  • @Felix Kling AFAIK PHP数组没有O(1)查找/插入/删除,所以它们不像哈希图那样嘎嘎叫 (104认同)
  • @Gabi:如果它像鸭子一样走路,像鸭子一样游泳,像鸭子一样呱呱叫...... PHP手册说:*PHP中的数组实际上是一个有序的地图.* (63认同)
  • @Gabi:PHP _are_哈希映射中数组的内部实现. (19认同)
  • @Gabi Purcaru相关:[PHP阵列的时间/空间复杂度](http://stackoverflow.com/questions/5641052/time-space-complexity-of-php-array). (12认同)
  • @Felix很高兴知道,谢谢你证明我错了! (6认同)
  • 这仍然不是HashMap,因为我不能将对象用作键:(. (3认同)

小智 31

根据您的需要,您可能对SPL Object Storage类感兴趣.

http://php.net/manual/en/class.splobjectstorage.php

它允许您使用对象作为键,具有计数接口,获取哈希和其他好东西.

$s = new SplObjectStorage;
$o1 = new stdClass;
$o2 = new stdClass;
$o2->foo = 'bar';

$s[$o1] = 'baz';
$s[$o2] = 'bingo';

echo $s[$o1]; // 'baz'
echo $s[$o2]; // 'bingo'
Run Code Online (Sandbox Code Playgroud)

  • 这个。boztek 你被低估了 (3认同)

Eri*_*ski 29

使用O(1)读取复杂度在PHP中创建类似HashMap的Java.

打开phpsh终端:

php> $myhashmap = array();
php> $myhashmap['mykey1'] = 'myvalue1';
php> $myhashmap['mykey2'] = 'myvalue2';
php> echo $myhashmap['mykey2'];
myvalue2
Run Code Online (Sandbox Code Playgroud)

$myhashmap['mykey2']在这种情况下,复杂性似乎是恒定时间O(1),这意味着当$ myhasmap的大小接近无穷大时,检索给定键的值所花费的时间保持不变.

php数组读取的证据是恒定时间:

通过PHP解释器运行:

php> for($x = 0; $x < 1000000000; $x++){
 ... $myhashmap[$x] = $x . " derp";
 ... }
Run Code Online (Sandbox Code Playgroud)

循环增加了10亿个键/值,将它们全部添加到散列映射大约需要2分钟,这可能会耗尽内存.

然后看看进行查找需要多长时间:

php> system('date +%N');echo "  " . $myhashmap[10333] . "  ";system('date +%N');
786946389  10333 derp  789008364
Run Code Online (Sandbox Code Playgroud)

那么PHP数组映射查找速度有多快?

10333是我们查找的关键.100万纳秒== 1毫秒.从密钥获取值所花费的时间是206万纳秒或大约2毫秒.如果数组为空,大约相同的时间.这对我来说似乎是不变的时间.

  • 对于占用一台计算机的整个内存(例如 8 GB)的数据集大小,查找时间为几毫秒。所以它“非常接近恒定时间,基本上是恒定时间”,但如果你想在数学上正确地将事情执行到无穷大的 100 亿个盒子,它就是 O(n log n)。我也可以挑剔。:) 我在这里使用恒定时间意味着“这不会成为你的瓶颈,兄弟,甚至不要绊倒狗”。 (3认同)

小智 13

$fruits = array (
    "fruits"  => array("a" => "Orange", "b" => "Banana", "c" => "Apple"),
    "numbers" => array(1, 2, 3, 4, 5, 6),
    "holes"   => array("first", 5 => "second", "third")
);

echo $fruits["fruits"]["b"]
Run Code Online (Sandbox Code Playgroud)

输出'香蕉'

取自http://in2.php.net/manual/en/function.array.php

  • @Diego` $ fruits = array(); $ fruits ['fruits'] = array('a'=>'Orange',...);`...实际上,你甚至可以直接做到这一点:`$ fruits ['fruits'] [ 'a'] ='橙色'; $ fruits ['holes'] ['first'] = 5; $ fruits ['numbers'] [] = 1;`你甚至不需要用`array()`来创建任何数组. (2认同)

Ger*_*eld 9

HashMap也可以使用字符串和整数以外的键,其中O(1)读取复杂度(取决于您自己的哈希函数的质量).

您可以自己创建一个简单的hashMap.hashMap的作用是使用散列作为索引/键将数据存储在数组中.散列函数偶尔会发生冲突(不常见,但可能会发生冲突),因此您必须在hashMap中为条目存储多个项目.那个简单的是一个hashMap:

class IEqualityComparer {
    public function equals($x, $y) {
        throw new Exception("Not implemented!");
    }
    public function getHashCode($obj) {
        throw new Exception("Not implemented!");
    }
}

class HashMap {
    private $map = array();
    private $comparer;

    public function __construct(IEqualityComparer $keyComparer) {
        $this->comparer = $keyComparer;
    }

    public function has($key) {
        $hash = $this->comparer->getHashCode($key);

        if (!isset($this->map[$hash])) {
            return false;
        }

        foreach ($this->map[$hash] as $item) {
            if ($this->comparer->equals($item['key'], $key)) {
                return true;
            }
        }

        return false;
    }

    public function get($key) {
        $hash = $this->comparer->getHashCode($key);

        if (!isset($this->map[$hash])) {
            return false;
        }

        foreach ($this->map[$hash] as $item) {
            if ($this->comparer->equals($item['key'], $key)) {
                return $item['value'];
            }
        }

        return false;
    }

    public function del($key) {
        $hash = $this->comparer->getHashCode($key);

        if (!isset($this->map[$hash])) {
            return false;
        }

        foreach ($this->map[$hash] as $index => $item) {
            if ($this->comparer->equals($item['key'], $key)) {
                unset($this->map[$hash][$index]);
                if (count($this->map[$hash]) == 0)
                    unset($this->map[$hash]);

                return true;
            }
        }

        return false;
    }

    public function put($key, $value) {
        $hash = $this->comparer->getHashCode($key);

        if (!isset($this->map[$hash])) {
            $this->map[$hash] = array();
        }

        $newItem = array('key' => $key, 'value' => $value);        

        foreach ($this->map[$hash] as $index => $item) {
            if ($this->comparer->equals($item['key'], $key)) {
                $this->map[$hash][$index] = $newItem;
                return;
            }
        }

        $this->map[$hash][] = $newItem;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使它起作用,你还需要一个哈希函数用于你的密钥和一个比较器的相等(如果你只有一些项目或另一个原因不需要速度你可以让哈希函数返回0;所有项目将是放入相同的桶,你会得到O(N)复杂性)

这是一个例子:

class IntArrayComparer extends IEqualityComparer {
    public function equals($x, $y) {
        if (count($x) !== count($y))
            return false;

        foreach ($x as $key => $value) {
            if (!isset($y[$key]) || $y[$key] !== $value)
                return false;
        }

        return true;
    }

    public function getHashCode($obj) {
        $hash = 0;
        foreach ($obj as $key => $value)
            $hash ^= $key ^ $value;

        return $hash;
    }
}

$hashmap = new HashMap(new IntArrayComparer());

for ($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 10; $j++) {
        $hashmap->put(array($i, $j), $i * 10 + $j);
    }
}

echo $hashmap->get(array(3, 7)) . "<br/>";
echo $hashmap->get(array(5, 1)) . "<br/>";

echo ($hashmap->has(array(8, 4))? 'true': 'false') . "<br/>";
echo ($hashmap->has(array(-1, 9))? 'true': 'false') . "<br/>";
echo ($hashmap->has(array(6))? 'true': 'false') . "<br/>";
echo ($hashmap->has(array(1, 2, 3))? 'true': 'false') . "<br/>";

$hashmap->del(array(8, 4));
echo ($hashmap->has(array(8, 4))? 'true': 'false') . "<br/>";
Run Code Online (Sandbox Code Playgroud)

这给出了输出:

37
51
true
false
false
false
false
Run Code Online (Sandbox Code Playgroud)

  • `IEqualityComparer`应该是一个`interface` (2认同)