TSet
被销毁时,其元素也将被销毁。键类型也必须是值类型。TSet<FString> FruitSet; //尚未分配内存
Add
FruitSet.Add(TEXT("Banana"));
FruitSet.Add(TEXT("Grapefruit"));
FruitSet.Add(TEXT("Pineapple"));
// FruitSet == [ "Banana", "Grapefruit", "Pineapple" ]
FruitSet.Add(TEXT("Pear"));
FruitSet.Add(TEXT("Banana"));
// FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear" ]
// Note:Only one banana entry.
此处的元素按插入顺序排列,但不保证这些元素在内存中实际保留此排序。如果是新集合,可能会保留插入排序,但插入和删除的次数越多,新元素不出现在末尾的可能性越大。
Emplace
代替 Add,避免插入集合时创建临时文件
FruitSet.Emplace(TEXT("Orange"));
// FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange" ]
Append
函数进行合并来插入另一个集合中的所有元素
TSet<FString> FruitSet2;
FruitSet2.Emplace(TEXT("Kiwi"));
FruitSet2.Emplace(TEXT("Melon"));
FruitSet2.Emplace(TEXT("Mango"));
FruitSet2.Emplace(TEXT("Orange"));
FruitSet.Append(FruitSet2);
// FruitSet == [ "Banana", "Grapefruit", "Pineapple", "Pear", "Orange", "Kiwi", "Melon", "Mango" ]
范围 - for
for (auto& Elem :FruitSet)
{
FPlatformMisc::LocalPrint( *FString::Printf(TEXT(" \"%s\"\n"), *Elem ));
}
// 依次输出 "Banana" "Grapefruit" "Pineapple" "Pear" "Orange" "Kiwi" "Melon" "Mango"
迭代器
for (auto It = FruitSet.CreateConstIterator(); It; ++It)
{
FPlatformMisc::LocalPrint( *FString::Printf(TEXT("(%s)\n"), *It ) );
}
Num
函查询集合中保存的元素数量
int32 Count = FruitSet.Num(); // Count == 8
Contains
函数查询是否包含特定元素
bool bHasBanana = FruitSet.Contains(TEXT("Banana")); // bHasBanana == true
bool bHasLemon = FruitSet.Contains(TEXT("Lemon")); // bHasLemon == false
FSetElementId
结构体可查找集合中某个键的索引。然后,就可使用该索引与 运算符[] 查找元素。
FSetElementId BananaIndex = FruitSet.Index(TEXT("Banana"));
// BananaIndex is a value between 0 and (FruitSet.Num() - 1)
FPlatformMisc::LocalPrint( *FString::Printf( TEXT(" \"%s\"\n"), *FruitSet[BananaIndex] ));
// Prints "Banana"
FSetElementId LemonIndex = FruitSet.Index(TEXT("Lemon"));
// LemonIndex is INDEX_NONE (-1)
FPlatformMisc::LocalPrint( *FString::Printf(TEXT(" \"%s\"\n"), *FruitSet[LemonIndex] ));
// Assert!
Find
返回指向元素数值的指针。
Find
,返回的指针也将为常量FString* PtrBanana = FruitSet.Find(TEXT("Banana")); // *PtrBanana == "Banana"
FString* PtrLemon = FruitSet.Find(TEXT("Lemon")); // PtrLemon == nullptr
Array
函数会返回一个 TArray,其中填充了 TSet 中每个元素的一份副本。
TArray<FString> FruitArray = FruitSet.Array();
// FruitArray == [ "Banana","Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" ] (order may vary)
Remove 函数可按索引移除元素,
FruitSet.Remove(0);
// FruitSet == [ "Grapefruit","Pineapple","Pear","Orange","Kiwi","Melon","Mango" ]
int32 RemovedAmountPineapple = FruitSet.Remove(TEXT("Pineapple"));
// RemovedAmountPineapple == 1
// FruitSet == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
int32 RemovedAmountLemon = FruitSet.Remove(TEXT("Lemon"));
// RemovedAmountLemon == 0
Empty
或 Reset
函数可将集合中的所有元素移除
TSet<FString> FruitSetCopy = FruitSet;
// FruitSetCopy == [ "Grapefruit","Pear","Orange","Kiwi","Melon","Mango" ]
FruitSetCopy.Empty();
// FruitSetCopy == []
TSet 可以排序。排序后,迭代集合会以排序的顺序显示元素,但下次修改集合时,排序可能会发生变化。由于排序不稳定,可能按任何顺序显示集合中支持重复键的等效元素。
Sort
函数指定排序顺序的二进制谓词
FruitSet.Sort([](const FString& A, const FString& B) {
return A > B; // sort by reverse-alphabetical order
});
// FruitSet == [ "Pear", "Orange", "Melon", "Mango", "Kiwi", "Grapefruit" ] (order is temporarily guaranteed)
FruitSet.Sort([](const FString& A, const FString& B) {
return A.Len() < B.Len(); // sort strings by length, shortest to longest
});
// FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ] (order is temporarily guaranteed)
TSet<FString> NewSet = FruitSet;
NewSet.Add(TEXT("Apple"));
NewSet.Remove(TEXT("Pear"));
// FruitSet == [ "Pear", "Kiwi", "Melon", "Mango", "Orange", "Grapefruit" ]
// NewSet == [ "Kiwi", "Melon", "Mango", "Orange", "Grapefruit", "Apple" ]
Reset
在不取消任何内存的情况下移除集合中的所有元素,从而产生slack
FruitSet.Reset();
// FruitSet == [ <invalid>, <invalid>, <invalid>, <invalid>, <invalid>, <invalid> ]
Reserve
函数可直接创建slack,例如在添加元素之前预分配内存
FruitSet.Reserve(10);
for (int32 i = 0; i < 10; ++i)
{
FruitSet.Add(FString::Printf(TEXT("Fruit%d"), i));
}
// FruitSet == [ "Fruit9", "Fruit8", "Fruit7" ..."Fruit2", "Fruit1", "Fruit0" ]
使用 Collapse
和 Shrink
函数可移除 TSet 中的全部slack。
// Remove every other element from the set.
for (int32 i = 0; i < 10; i += 2)
{
FruitSet.Remove(FSetElementId::FromInteger(i));
}
// FruitSet == ["Fruit8", <invalid>, "Fruit6", <invalid>, "Fruit4", <invalid>, "Fruit2", <invalid>, "Fruit0", <invalid> ]
FruitSet.Shrink();
// FruitSet == ["Fruit8", <invalid>, "Fruit6", <invalid>, "Fruit4", <invalid>, "Fruit2", <invalid>, "Fruit0" ]
Compact
或 CompactStable
函数,将空白空间组合在一起,为调用 Shrink 做好准备
FruitSet.CompactStable();
// FruitSet == ["Fruit8", "Fruit6", "Fruit4", "Fruit2", "Fruit0", <invalid>, <invalid>, <invalid>, <invalid> ]
FruitSet.Shrink();
// FruitSet == ["Fruit8", "Fruit6", "Fruit4", "Fruit2", "Fruit0" ]
只要类型具有 运算符==
和非成员 GetTypeHash
重载,就可为TSet所用,因为此类型既是元素又是键。然而,不便于重载这些函数时可将类型作为键使用。在这些情况下,可对 DefaultKeyFuncs
进行自定义。为键类型创建 KeyFuncs
,必须定义两个typedef和三个静态函数,如下所示:
KeyInitType
—— 用于传递键的类型。通常抽取自ElementType模板参数。ElementInitType
—— 用于传递元素的类型。同样通常抽取自ElementType模板参数,因此与KeyInitType相同。KeyInitType GetSetKey(ElementInitType Element)
——返回元素的键。在集合中,通常是元素本身。bool Matches(KeyInitType A, KeyInitType B)
—— 如果 A
和 B
等值将返回 true
,否则返回 false
。uint32 GetKeyHash(KeyInitType Key)
—— 返回 Key
的散列值。KeyInitType
和 ElementInitType
是键/元素类型普通传递惯例的typedef。它们通常为浅显类型的一个值和非浅显类型的一个常量引用。请注意,集合的元素类型也是键类型,因此 DefaultKeyFuncs
仅使用一种模板参数 ElementType
定义两者。
TSet
假定在 DefaultKeyFuncs
中使用 Matches
进行对比结果为相等的两个项也将在 KeyFuncs
的 GetKeyHash
中返回相同的值。
CountBytes
和 GetAllocatedSize
函数用于估计内部数组的当前内存使用情况。CountBytes
接受 FArchive
参数,而 GetAllocatedSize
则不接受。这些函数常用于统计报告。
Dump
函数接受 FOutputDevice
并写出关于集合内容的实现信息。还有一个名为 DumpHashElements
的函数,可列出来自所有散列条目的所有元素。这些函数常用于调试。
原文:https://www.cnblogs.com/shiroe/p/14695417.html