Fork me on GitHub

关于 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 }

 打印结果

  

 

posted @ 2023-05-14 22:52  索智源  阅读(359)  评论(0编辑  收藏  举报