Мне нужен PHP-объект, похожий на HashMap в Java, но я не нашел, когда я googled, поэтому, если кто-то знает, как я могу имитировать HashMaps в PHP, вам будет полезно получить помощь.
Есть ли эквивалент Java HashMap в PHP?
Ответ 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"]
выводит "Банан"
Ответ 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