Подтвердить что ты не робот

Есть ли эквивалент Java HashMap в PHP?

Мне нужен PHP-объект, похожий на HashMap в Java, но я не нашел, когда я googled, поэтому, если кто-то знает, как я могу имитировать HashMaps в PHP, вам будет полезно получить помощь.

4b9b3361

Ответ 1

Массивы в PHP могут иметь структуру ключевых значений.

Ответ 2

В зависимости от того, что вы хотите, вас может заинтересовать класс хранения объектов SPL.

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'

Ответ 3

Создайте Java как HashMap в PHP с сложностью чтения (1).

Откройте phpsh-терминал:

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

Сложность $myhashmap['mykey2'] в этом случае представляется постоянным временем O (1), что означает, что по мере приближения к $myhasmap бесконечности количество времени, которое требуется для получения значения с учетом ключа, остается неизменным.

Доказательство того, что чтение php-массива является постоянным:

Запустите это через интерпретатор PHP:

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

Цикл добавляет 1 миллиард ключей/значений, для добавления всех их в хэш-карту требуется около 2 минут.

Затем посмотрите, сколько времени требуется для поиска:

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

Итак, как быстро просматривается карта массива PHP?

10333 - это ключ, который мы искали. 1 миллион наносекунд == 1 миллисекунда. Время, затрачиваемое на получение стоимости от ключа, составляет 2,06 миллиона наносекунд или около 2 миллисекунд. Примерно столько же времени, если массив был пустым. Это выглядит как постоянное время для меня.

Ответ 4

$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"]

выводит "Банан"

взято из http://in2.php.net/manual/en/function.array.php

Ответ 5

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

Для его функционирования вам также нужна хеш-функция для вашего ключа и компаратора для равенства (если у вас есть только несколько элементов или по другой причине вам не нужна скорость, вы можете позволить хэш-функции вернуть 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/>";

Что дает в качестве вывода:

37
51
true
false
false
false
false