TArray:Templated dynamic array
-
其中ArrayNum是数组元素的实际个数,
-
ArrayMax是数组最大可容纳元素的数量
-
AllocatorInstance是数组的内存分配器
-
数组实际占用的内存,只有这3个成员变量的内存(2个int 1个指针)
-
数组内容为常量,运算符[] 将返回常量引用
-
调用 Heapify 函数可将现有数组转换为堆。默认用<排序
-
堆相关的操作函数:HeapPush HeapPop HeapPopDiscard (会排序)
-
关于slack
-
Reset 可调整数组的内存大小,减少重新分配内存
-
GetSlack 函数可找出数组中的Slack量,空闲量
-
GetSlack 等同 Max 和 Num 间的差值
-
使用 Shrink 函数可移除所有Slack内存,不影响已存在元素。
优化TIPS:
- 如果您知道需要添加多少项目,或者您大致了解上限,那么您可以事先预留空间 Reserve。
- 当把TArrays作为函数参数使用时,要传递引用 TArray<int32>&。
- 在移除元素时,减少移动后继元素. Array.RemoveAtSwap(3); RemoveSwap、RemoveAllSwap。
- 大多数TArray删除函数会用"bAllowShrinking"参数,短暂存在的数组会浪费时间和缓存.
- 让类型更易使用 如下:
- typedef TArray<Shape*, TInlineAllocator<16>> ShapeArrayType;
- ShapeArrayType MyShapeArray;
使用TInlineAllocator 或 TFixedAllocator
- 非常了解在通常情况下会出现在您的数组中的最大数量元素
- TArray<Shape*, TInlineAllocator<16>> MyShapeArray;
- 前16个添加到数组的元素无动态分配
- 在17个元素之后,所有元素都被移动到第二分配器(比如堆分配器)以供存储
- TFixedAllocator 没有第二分配器;如果固定存储部分没有空间了,代码会产生错误。
typedef typename TChooseClass<
AllocatorType::NeedsElementType,
typename AllocatorType::template ForElementType<ElementType>,
typename AllocatorType::ForAnyElementType
>::Result ElementAllocatorType;
protected:
template<typename ElementType, typename AllocatorType>
friend class TIndirectArray;
ElementAllocatorType AllocatorInstance;
SizeType ArrayNum;
SizeType ArrayMax;
TArray的几种创建和初始化方法 包含右值移动
// 创建,初始化
TArray<int32> Arr1({1,2,3,4,5});
TArray<int32> Arr2 = {6,7,8,9,0};
// 右值移动 移动后Arr2就空了 MoveTemp == std::move<T>(t);
TArray<int32> Arr3 = MoveTemp(Arr2);
PrintArray(Arr2);
PrintArray(Arr3);
TArray<int32> ArrNum;
ArrNum.Init(1, 2);
ArrNum = {10,10};
PrintArray(ArrNum);
TArray添加元素的操作
// 添加元素
ArrNum.Reset(); // 重置
ArrNum.Reserve(10); // 设置大小
ArrNum.Push(1);
ArrNum.Add(2);
ArrNum.Emplace(3);
ArrNum.AddUnique(4);// 添加不重复的元素
ArrNum.Append({8,9,0});
ArrNum += {5,6,7};
PrintArray(ArrNum);
内置的排序算法
// 快速排序 堆排序 归并排序
ArrNum.Sort();
ArrNum.HeapSort();
ArrNum.StableSort();
PrintArray(ArrNum);
删除元素的操作
// 删除元素
ArrNum.Remove(10);// 1 2 3 4 5
ArrNum.Pop();// 1 2 3 4
ArrNum.RemoveSingle(1);// 2 3 4
PrintArray(ArrNum);
常用的一些查询函数
UE_LOG(TestLog, Warning, TEXT("ArrNum[0] is %d"), ArrNum[0]);
UE_LOG(TestLog, Warning, TEXT("ArrNum.Top() is %d"), ArrNum.Top());
UE_LOG(TestLog, Warning, TEXT("ArrNum.Last() is %d"), ArrNum.Last());
UE_LOG(TestLog, Warning, TEXT("ArrNum.Num() is %d"), ArrNum.Num());
UE_LOG(TestLog, Warning, TEXT("ArrNum.Max() is %d"), ArrNum.Max());
UE_LOG(TestLog, Warning, TEXT("ArrNum.GetData() is %d"), ArrNum.GetData());
UE_LOG(TestLog, Warning, TEXT("ArrNum.GetTypeSize() is %d"), ArrNum.GetTypeSize());
UE_LOG(TestLog, Warning, TEXT("ArrNum.GetSlack() is %d"), ArrNum.GetSlack());
UE_LOG(TestLog, Warning, TEXT("ArrNum.GetAllocatedSize() is %d"), ArrNum.GetAllocatedSize());
// 返回下标
if (ArrNum.Find(2) > 0)
{
UE_LOG(TestLog, Warning, TEXT("ArrNum.Find(2)"));
}
if (ArrNum.Contains(2))
{
UE_LOG(TestLog, Warning, TEXT("ArrNum.Contains(2)"));
}
for(auto it = ArrNum.CreateConstIterator(); it; ++it)
{
if(it)
{
UE_LOG(TestLog, Warning, TEXT("ArrNum it at %d = %d"), it.GetIndex(), *it);
}
}
TArray<FString> Arr = { TEXT("A"), TEXT("B"), TEXT("C") };
谓词查找:检查此数组是否包含谓词为真的元素
// 谓词查找:检查此数组是否包含谓词为真的元素
bool bFindHas3 = ArrNum.ContainsByPredicate(
[](const int32& n)
{
return n == 3;
});
if (bFindHas3)
{
UE_LOG(TestLog, Warning, TEXT("ArrNum.ContainsByPredicate(n == 3)"));
}
3种遍历方法
for (const auto& s : Arr)
{
UE_LOG(TestLog, Warning, TEXT("%s"), *s);
}
for (int i = 0; i < Arr.Num(); i++)
{
UE_LOG(TestLog, Warning, TEXT("%d - %s"), i, *Arr[i]);
}
for (auto It = Arr.CreateConstIterator(); It; ++It)
{
UE_LOG(TestLog, Warning, TEXT("%s"), *(*It));
}
网友评论