TMap
官方文档:Map Containers in Unreal Engine | 虚幻引擎 5.5 文档 | Epic Developer Community (epicgames.com)
TMap
与 TSet
类似,它们的结构均基于对键进行散列运算。但与 TSet
不同的是,此容器将数据存储为键值对(TPair<KeyType, ValueType>
),只将键用于存储和获取。
键值对(Key-Value Pair)是一种常见的数据结构,它将一个值(Value)与一个唯一的键(Key)相关联,通过键可以快速地访问和获取对应的值。
映射有两种类型:TMap
和 TMultiMap
。
(1)TMap
中的键是唯一的,在 TMap
中添加新的键值时,若所用的键与原有的对相同,新对将替换原有的对。
(2)TMultiMap
可存储多个相同的键,在 TMultiMap
中,容器可以同时存储新对和原有的对。
在 TMap
中,键值对被视为映射的元素类型,相当于每一对都是个体对象。
注意:映射的支持数据结构是稀疏数组,这种数组可有效支持元素之间的空位。当元素从映射中被移除时,稀疏数组中就会出现空位。将新的元素添加到数组可填补这些空位。但是,即便 TMap
不会打乱元素来填补空位,指向映射元素的指针仍然可能失效,因为如果存储器被填满,又添加了新的元素,整个存储可能会重新分配。
TMap
是同质容器,就是说它所有元素的类型都应完全相同。
TMap
是值类型,支持通常的复制、赋值和析构函数运算,以及它的元素的强所有权。在映射被销毁时,它的元素都会被销毁。
TMap
是散列容器,这意味着键类型必须支持 GetTypeHash
函数,并提供 运算符==
来比较各个键是否等值。
TMap
可使用任选分配器来控制内存分配行为。但不同于 TArray
,这些是集合分配器(集合分配器(TSetAllocator
类)定义映射应使用的散列桶数量,以及应使用哪个标准UE4分配器来存储散列和元素。)。
TMap
模板最后一个参数——KeyFuncs,该参数告知映射如何从元素类型获取键,如何比较两个键是否相等,以及如何对键进行散列计算。
注意:与 TArray
不同的是,内存中 TMap
元素的相对排序既不可靠也不稳定,对这些元素进行迭代很可能会使它们返回的顺序和它们添加的顺序有所不同。这些元素也不太可能在内存中连续排列。
1.创建和填充映射
创建一个MapActor类并继承于Actor,其与TArray创建方法一样就不一一详细介绍;
Actor类头文件增添代码:
public:
UFUNCTION(BlueprintCallable)
void InitMap();
UPROPERTY(BlueprintReadWrite,EditAnywhere,Category = "Name|Fruit")//其在蓝图内可读可写
TMap<int32, FString> MyFruitMap;
用 UPROPERTY
宏和一个可编辑的关键词(EditAnywhere
、EditDefaultsOnly
或 EditInstanceOnly
)标记 TMap
,即可在编辑器中添加和编辑元素。
源文件函数代码:
void AMapActor::InitMap()
{
TMap<int32, FString> FruitMap;
//填充映射的标准方法是调用带一个键和值的 Add 函数
FruitMap.Add(5, TEXT("Banana"));
FruitMap.Add(2, TEXT("Grapefruit"));
FruitMap.Add(7, TEXT("Pineapple"));
// FruitMap == [
// { Key:5, Value:"Banana" },
// { Key:2, Value:"Grapefruit" },
// { Key:7, Value:"Pineapple" }
// ]
//每个键都是唯一的,如果尝试添加重复键,将会将之前键值为2的“Grapefruit”被“Pear”替代
FruitMap.Add(2, TEXT("Pear"));
// FruitMap == [
// { Key:5, Value:"Banana" },
// { Key:2, Value:"Pear" },
// { Key:7, Value:"Pineapple" }
// ]
//Add函数可接受不带值的键,调用Add函数时其本身被重载,值将被默认构造
FruitMap.Add(4);
// FruitMap == [
// { Key:5, Value:"Banana" },
// { Key:2, Value:"Pear" },
// { Key:7, Value:"Pineapple" },
// { Key:4, Value:"" }
// ]
//TMap和TArray大致一样,其也可使用Emplace代替Add,防止插入映射时创建临时文件
//此处直接将键和值传递给了各自的构造函数,其对int32键实际上没有影响,但避免了为该值创建临时FString
FruitMap.Emplace(3, TEXT("Orange"));
// FruitMap == [
// { Key:5, Value:"Banana" },
// { Key:2, Value:"Pear" },
// { Key:7, Value:"Pineapple" },
// { Key:4, Value:"" },
// { Key:3, Value:"Orange" }
// ]
TMap<int32, FString> FruitMap2;
FruitMap2.Emplace(4, TEXT("Kiwi"));
FruitMap2.Emplace(9, TEXT("