关于 UE4 的 TSet
- TSet是一种快速容器类,(通常)用于在排序不重要的情况下存储唯一元素。
- TSet 类似于 TMap 和 TMultiMap,但有一个重要区别:TSet 是通过对元素求值的可覆盖函数,使用数据值本身作为键,而不是将数据值与独立的键相关联。
- TSet 可以非常快速地添加、查找和删除元素。默认情况下,TSet 不支持重复的键,但使用模板参数可激活此行为。
- TSet 也是值类型,支持常规复制、赋值和析构函数操作。TSet 被销毁时,其元素也将被销毁。键类型也必须是值类型。
- TSet 会直接使用 运算符== 比较元素,使用 GetTypeHash 对其进行散列,然后使用标准的堆分配器
为了测试 TSet 的打印,我将测试代码放到了一个 Actor 的 BginPlay 方法中进行打印测试,代码如下:
其使用了迭代器 与 For Each 两种遍历方法
1 // Called when the game starts or when spawned 2 void ASetActor::BeginPlay() 3 { 4 Super::BeginPlay(); 5 6 // 迭代器遍历 TSet 7 auto Foreach = [](TSet<int32> _arr)->void 8 { 9 if (_arr.Num() > 0) 10 { 11 for (TSet<int32>::TConstIterator it = _arr.CreateConstIterator(); it; ++it) 12 { 13 UE_LOG(LogTemp, Display, TEXT("Foreach: SetNum == %d"), *it); 14 } 15 UE_LOG(LogTemp, Display, TEXT(" ========================= ")); 16 } 17 }; 18 19 // foreach 遍历 TSet 20 auto Foreach_2 = [](TSet<int32> _arr)->void 21 { 22 if (_arr.Num() > 0) 23 { 24 for (auto val : _arr) 25 { 26 UE_LOG(LogTemp, Display, TEXT("Foreach_2: SetNum == %d"), val); 27 } 28 UE_LOG(LogTemp, Display, TEXT(" ========================= ")); 29 } 30 }; 31 32 TSet<int32> SetNum_1; 33 TSet<int32> SetNum_2; 34 TSet<int32> SetNum_3; 35 TSet<int32> SetNum_4; 36 SetNum_1.Add(1); 37 SetNum_1.Add(22); 38 SetNum_1.Add(333); 39 SetNum_2.Add(2); 40 SetNum_3.Add(3); 41 SetNum_4.Add(4); 42 SetNum_4.Add(1324); 43 44 // 增加元素 45 // 此处的元素按插入顺序排列,但不保证这些元素在内存中实际保留此排序。如果是新集合,可能会保留插入排序,但插入和删除的次数越多,新元素不出现在末尾的可能性越大。 46 SetNum_1.Add(111); // 向集合中添加一个元素,返回值是一个bool的指针,该指针的设置取决于元素是否已经在 Set 中,参数传入后会直接调用 Emplace 方法 47 Foreach(SetNum_1); 48 SetNum_2.Emplace(111); // 向集合中添加一个元素,参数是要转发给 Set 构造函数的参数。返回值是一个bool的指针,该指针的设置取决于元素是否已经在 Set 中,该方法也是 Add 调用的方法。 49 Foreach(SetNum_2); 50 51 // Set 合并 52 SetNum_1.Append(SetNum_2); // 将另一个集合中的所有项添加到当前的集合中,联合而不是新建一个集合存储。其实现方式为分配内存后使用ForEach Add 添加 53 Foreach(SetNum_1); 54 55 // Set 交集 56 SetNum_1 = SetNum_1.Intersect(SetNum_2); // 交集后只保存双方都存在的元素,其结果在返回值中,并不会改变参与判断的两个 Set 57 Foreach(SetNum_1); 58 59 // Set 并集 60 SetNum_1 = SetNum_1.Union(SetNum_3); // 只从参数 Set 中取当前 Set 没有的元素合并,其结果在返回值中,并不会改变参与判断的两个 Set 61 Foreach(SetNum_1); 62 63 // 查询集合中元素的数量 64 UE_LOG(LogTemp, Display, TEXT(" SetNum_1.Num(): %d "), SetNum_1.Num()); 65 Foreach(SetNum_1); 66 67 // 查询是否包含某个元素 68 if (SetNum_1.Contains(1)) 69 { 70 UE_LOG(LogTemp, Display, TEXT("SetNum_1.Contains(1) == Ture")); 71 Foreach(SetNum_1); 72 } 73 else 74 { 75 UE_LOG(LogTemp, Display, TEXT("SetNum_1.Contains(1) == False")); 76 Foreach(SetNum_1); 77 } 78 79 // 查找元素,如果存在则返回元素指针 80 int32* Num = SetNum_1.Find(2); 81 if (Num) 82 { 83 UE_LOG(LogTemp, Display, TEXT(" int32* Num = SetNum_1.Find(2)== Ture Num = %d "), *Num); 84 Foreach(SetNum_1); 85 } 86 else 87 { 88 UE_LOG(LogTemp, Display, TEXT(" int32* Num == NULL ")); 89 Foreach(SetNum_1); 90 } 91 92 // 删除元素 93 SetNum_1.Remove(2); // 删除集合中与指定键匹配的所有元素。参数为要删除的数。其返回值是删除元素的个数。 94 Foreach(SetNum_1); 95 96 97 // 删除所有元素 98 SetNum_1.Empty(); // 将集合中所有元素清空;其参数为预留空间数量,给后边加入的元素预留,参数默认是0 99 SetNum_1.Reset(); // 与 Empty 不同的是,Reset 删除完所有元素后会保留所有空间 100 Foreach(SetNum_1); 101 102 }
打印结果