자바에서 HashMap과 비슷한 PHP 오브젝트가 필요한데 구글에서 검색했을 때 찾을 수 없었기 때문에 PHP에서 HashMaps를 모방할 수 있는 방법을 아는 사람이 있다면 도움이 될 것 같습니다.
질문에 대한 답변
PHP의 어레이는 Key Value 구조를 가질 수 있습니다.
읽기 복잡도가 O(1)인 PHP의 HashMap과 같은 Java를 만듭니다.
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";
... }
루프는 10억 개의 키/값을 추가합니다.이러한 값을 모두 해시맵에 추가하는 데 약 2분이 소요되며, 이로 인해 메모리가 소진될 수 있습니다.
그런 다음 조회를 수행하는 데 걸리는 시간을 확인합니다.
php> system('date +%N');echo "
" . $myhashmap[10333] . "
";system('date +%N'); 786946389
10333 derp
789008364
그러면 PHP 어레이 맵 검색은 얼마나 빠릅니까?
그10333
100만 나노초 == 1밀리초입니다.키에서 값을 얻는 데 걸리는 시간은 206만나노초(약 2밀리초)입니다.어레이가 비어 있는 경우와 거의 같은 시간.내게는 이 시간이 항상처럼 보인다.
원하는 항목에 따라 SPL Object Storage 클래스에 관심이 있을 수 있습니다.
http://php.net/manual/en/class.splobjectstorage.php
개체를 키로 사용할 수 있고, 셀 인터페이스가 있으며, 해시 및 기타 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'
$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 에서 취득한 것
읽기 복잡도가 O(1)인 문자열 및 정수 이외의 키와도 동작하는 HashMap(해시 함수의 품질에 따라 다름).
간단한 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