Is there Java HashMap equivalent in PHP?

前端 未结 5 1634

I need PHP object similar to HashMap in Java, but I didn\'t find when I googled, so if someone knows how I can mimic HashMaps in PHP, help would be appreciated.

相关标签:
5条回答
  • 2020-12-02 12:15
    $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"]
    

    outputs 'Banana'

    taken from http://in2.php.net/manual/en/function.array.php

    0 讨论(0)
  • 2020-12-02 12:28

    Create a Java like HashMap in PHP with O(1) read complexity.

    Open a phpsh terminal:

    php> $myhashmap = array();
    php> $myhashmap['mykey1'] = 'myvalue1';
    php> $myhashmap['mykey2'] = 'myvalue2';
    php> echo $myhashmap['mykey2'];
    myvalue2
    

    The complexity of the $myhashmap['mykey2'] in this case appears to be constant time O(1), meaning that as the size of $myhasmap approaches infinity, the amount of time it takes to retrieve a value given a key stays the same.

    Evidence the php array read is constant time:

    Run this through the PHP interpreter:

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

    The loop adds 1 billion key/values, it takes about 2 minutes to add them all to the hashmap which may exhaust your memory.

    Then see how long it takes to do a lookup:

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

    So how fast is the PHP array map lookup?

    The 10333 is the key we looked up. 1 million nanoseconds == 1 millisecond. The amount of time it takes to get a value from a key is 2.06 million nanoseconds or about 2 milliseconds. About the same amount of time if the array were empty. This looks like constant time to me.

    0 讨论(0)
  • 2020-12-02 12:31

    Depending on what you want you might be interested in the SPL Object Storage class.

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

    It lets you use objects as keys, has an interface to count, get the hash and other goodies.

    $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'
    
    0 讨论(0)
  • 2020-12-02 12:33

    HashMap that also works with keys other than strings and integers with O(1) read complexity (depending on quality of your own hash-function).

    You can make a simple hashMap yourself. What a hashMap does is storing items in a array using the hash as index/key. Hash-functions give collisions once in a while (not often, but they may do), so you have to store multiple items for an entry in the hashMap. That simple is a 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;
        }
    }
    

    For it to function you also need a hash-function for your key and a comparer for equality (if you only have a few items or for another reason don't need speed you can let the hash-function return 0; all items will be put in same bucket and you will get O(N) complexity)

    Here is an example:

    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/>";
    

    Which gives as output:

    37
    51
    true
    false
    false
    false
    false
    
    0 讨论(0)
  • 2020-12-02 12:38

    Arrays in PHP can have Key Value structure.

    0 讨论(0)
提交回复
热议问题