为什么 Symfony 提供一个 OrderedHashMap

Why does Symfony provide an OrderedHashMap

Symfony 提供了一个OrderedHashMap。它的 documentation states

Unlike associative arrays, the map keeps track of the order in which keys were added and removed. This order is reflected during iteration.

我对这个说法感到困惑,因为我认为 PHP 关联数组实际上是已经有序的映射。我在SO上发现了这个问题,证实了我之前的假设:Are PHP Associative Arrays ordered?

我想知道,如果 Symfony 开发者不知道 PHP 数组已经是有序映射,或者我是否不理解 Symfony 的 OrderedHashMap

的作用

当然PHP的数组是一个ordered-map.

但是 Symfony 的 OrderedHashMap 与 PHP 的数组有一些不同的行为(例如,features)。

OrderedHashMap支持迭代时并发修改。这意味着您可以在 foreach 循环中插入和删除元素,迭代器将相应地反映这些更改。但是迭代中的array是复制的(Copy-On-Write),任何修改都不会体现在循环中。

$map = new OrderedHashMap();
$map[1] = 1;
$map[2] = 2;
$map[3] = 3;

foreach ($map as $index => $value) {
    echo "$index: $value\n"
    if (1 === $index) {
        $map[1] = 4;
        $map[] = 5;
    }
}

如果您使用 array,您将得到不同的输出。在 array 的迭代中,循环不会看到数字 5.

关于“为什么?”:在Symfony's codebase中搜索。只有 一个 地方使用 OrderedHashMap,用于存储表单的 children。 new InheritDataAwareIterator($this->children) 使用它进行迭代。所以我认为答案是帮助处理表单的 children.

感谢@fishbone:

So the benefit is not the ordering but the ability to modify it in loops.

一般来说,不仅在 Symfony 的上下文中,除了附加的已实现功能之外,面向对象的结构优于原始类型,例如 intstringarray,因为它们可以注入 class 进行单元测试。

面向对象的结构也可以执行不变量,而原始类型只能保存没有任何行为的数据。