objective-c中常用数据结构的总结
cocoa提供的结构体
-
NSRange
typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange;用于表示事物的范围,即从location开始,length长度的范围。
NSRange的创建
// 方法1 NSRange range; range.location = 3; range.length = 2; //方法2 range = (NSRange){5,3}; NSRange r2 = {4,5}; //方法3 NSRange r3 = {.location = 3,.length = 5}; //方法4(OC推荐) NSRange r4 = NSMakeRange(3, 3); //将NSRange转化为NSString NSString *str = NSStringFromRange(r4);在字符串截取时会用到NSRange
-
GFloat、CGPoint、CGSize和CGRect(几何数据类型)
typedef float CGFloat;// 32-bit typedef double CGFloat;// 64-bit struct CGPoint { CGFloat x; CGFloat y; }; // 表示坐标轴上的一个点。 typedef struct CGPoint CGPoint; struct CGSize { CGFloat width; CGFloat height; }; //表示图像的长和宽。 typedef struct CGSize CGSize; struct CGRect { CGPoint origin; CGSize size; }; //表示一个形状。 typedef struct CGRect CGRect; //使用CGRect数据结构的高度和宽度可以是负数,其表示的含义上相对于CGPoint的相对值。 //就是说:原点[0,0],长宽[10,10]的形状相当于原点[10,10],长宽是[-10,-10]的形状。CGPoint、CGSize和CGRect的创建和使用
CGPoint cgp = CGPointMake(0.0f,0.0f); CGSize cgs = CGSizeMake(10.0f,10.0f); CGRect cgr = CGRectMake(cgp.x,cgp.y,cgs.width,cgs.height); NSLog(@"%@",NSStringFromCGPoint(cgp)); NSLog(@"%@",NSStringFromCGSize(cgs)); NSLog(@"%@",NSStringFromCGRect(cgr));
字符串
创建字符串
//函数原型,工厂方法
+ (id) stringWithFormat: (NSString *)format,...;
使用方法
NSString *string = [NSString stringWithFormat:@"This is a test,output the number:%d.",5];
NSLog(@"%@",string);
字符串的大小
//函数原型 返回字符串的长度(也就是字符串的个数)
- (NSUInteger) length;
使用方法
NSUInteger num = [str length];
字符串的比较
//1.比较相同,相同返回YES
- (BOOL)isEqualToString:(NSString *)aString;
//2.字典序比较
- (NSComparisonResult)compare:(NSString *)string;
//
//enum {
// NSOrderedAscending = -1,
// NSOrderedSame,
// NSOrderedDescending
//};
//typedef NSInteger NSComparisonResult;
//NSOrderedAscending(升序),NSOrderedSame(同序),NSOrderedDescending(降序)
//NSOrderedDescending
//3.匹配字符串头
func hasPrefix(_ str: String) -> Bool
//4.匹配字符串尾
- (BOOL)hasSuffix:(NSString *)str;
使用方法
NSString *str0 = @"testcoding";
NSString *str1 = @"testcoding";
if([str0 isEqualToString:str1])
{
NSLog(@"字符串完全相等");
}
if([str0 hasPrefix:@"test"])
{
NSLog(@"字符串str0以test开头");
}
if([str1 hasSuffix:@"coding"])
{
NSLog(@"str1字符串以coding结尾");
}
NSString *string01 = @"this is a String";
NSString *string02 = @"This is a String";
BOOL result = [string01 compare:string02] = = NSOrderedDescending;
NSLog(@"result:%d",result);
//字符串对比:NSOrderedAscending(升序),NSOrderedSame(同序),NSOrderedDescending(降序)
//NSOrderedDescending 判断两对象值的大小(按字母顺序进行比较,string02小于string01为真)
NSString *string01 = @"this is a String!";
NSString *string02 = @"This is a String!";
BOOL result = [string01 compare:string02
options:NSCaseInsensitiveSearch | NSNumericSearch] = = NSOrderedSame;
NSLog(@"result:%d",result);
//NSCaseInsensitiveSearch:不区分大小写比较 NSLiteralSearch:进行完全比较,区分大小写
//NSNumericSearch:比较字符串的字符个数,而不是字符值。
//判断的方法可以利用 NSString 类别中 caseInsensitiveCompare: 所回传 -1、0 或是 1 的数值,判定两个
//字串之间得排序关系
字符串的遍历
//
- (unichar)characterAtIndex:(NSUInteger)index;
使用方法
NSString *str = @"TEST";
int count = [str length];
//遍历字符串中的每一个字符
for(int i =0; i < count; i++) {
char c = [str characterAtIndex:i];
NSLog(@"字符串第 %d 位为 %c",i,c);
}
字符串内是否包含别的字符串
//传递一个NSString对象,传递的参数是需要查找的字符串,它会返回一个NSRange结构体,表示这个字符串相匹配的
//范围。如果没有找到,就返回NSNotFound。
- (NSRange) rangeOfstring:(String *) aString;
使用方法
NSString *str = @"myFirstExampleAndDemo";
NSRange range = [str rangeOfString:@"Example"];
//返回值为{7,7}。
可变性
NSString是不可变的,一旦创建就不能改变,只能对指针重新赋值。如果需要一个可变的字符串类型,需要使用NSMutableString。NSString类似java中的String,NSMutableString类似java中的StringBuffer或StringBuilder。
可变字符串NSMutableString
创建字符串
//声明一个指定长度的NSMutableString,但是这个长度并不会限制使用。使用者可以超过其长度限制
+ (id) stringWithCapacity:(NSUInteger) capacity;
添加字符串
//两者都是将新字符串加入旧字符串最后。
- (void) appendString: (NSString *)aString;
- (void) appendFormat: (NSString *)format, ...;
删除字符串
//删除指定位置的字符串
- (void) deleteCharactersInRange: (NSRange) aRange;
集合类
NSArray
NSArray是不可变的数组类型,其中可以存放OC对象。不能添加或者删除元素。也不能对其中的元素进行修改。
- 只能存储OC的对象,不能存储原始C语言数据类型。
- 不能在其中存放null(nil)
创建NSArray
//通过arrayWithObjects可以创建有初始值的新array。
NSArray *array1 = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
//注意第二种方法,最后不能加nil。并且元素中不能有nil。
NSArray *array2 = @[@"one",@"two",@"three"];
使用
//通过array1.count得到数组的长度(对象的个数)
array1.count;
//通过array1[i]进行数组内元素的查找。
array1[i];
//也可以通过函数得到相应的值
- (ObjectType)objectAtIndex:(NSUInteger)index;
[array1 objectAtIndex: 下标];
//通过函数得到给定索引集对象的数组。
- (NSArray<ObjectType> *)objectsAtIndexes:(NSIndexSet *)indexes;
//判断数组中是否有某个对象
- (BOOL)containsObject:(ObjectType)anObject;
NSMutableArray
NSMutableArray是可变数组,可以随意添加或者删除数组中的元素。提升了灵活性,但是降低了安全性。
创建NSArray
//类似NSMutableString,这个容量并不会限制其真正的长度,可以无限制的插入元素。
//声明容量的目的只是为了让Cocoa能更好的对其进优化。
+ (void) arrayWithCapacity: (NSUInterger) numItems;
添加元素
//将新元素添加至数组的最后。
- (void) addObject:(id) anObject;
//在指定位置插入元素。
- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
//在指定位置插入数组。注意:indexes中的index个数必须等于atIndexes中元素的个数。
- (void)insertObjects:(NSArray<ObjectType> *)objects atIndexes:(NSIndexSet *)indexes;
NSArray *array1 = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
NSMutableArray *mutableArray2 = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16", nil];
NSMutableIndexSet *set = [[NSMutableIndexSet alloc] init];
//此处set中元素的个数必须等于array1中元素的个数。不然会报错。
[set addIndex:0];
[set addIndex:1];
[set addIndex:5];
[mutableArray2 insertObjects:array1 atIndexes:set];
for (int i =0; i<mutableArray2.count; i++) {
NSLog(@"%@",mutableArray2[i]);
}
输出结果:
删除元素
//删除相应位置上的元素。
- (void) removeObjectAtIndex:(NSUInteger) index;
//删除最后一个元素。
- (void)removeLastObject;
//删除所有元素。
- (void)removeAllObjects;
//删除索引集中索引位置上的元素,格式如上
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
替换元素
//替换目标索引处的元素
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;
//替换目标索引集中索引位置上的元素,格式如上
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects;
枚举器
相当于java中的迭代器。用于对于集合类的快速遍历。
创建一个枚举器
//通过这个方法从数组(Array)中得到相应的正向枚举器(向后遍历)。
- (NSEnumerator *)objectEnumerator;
NSEnumerator *enumerator = [array objectEnumerator];
//还有反向枚举器(从后向前遍历)
NSEnumerator *enumerator = [array reverseObjectEnumerator];
使用方法
- (id) nextObject;
while(id flag = [enumerator nextObject]){
NSLog(@"%@",flag);
}
//每次通过nextObject得到下一个值,然后通过判断是否为nil决定循环是否结束。这也是array中不能出现nil的原因之一。
快速枚举
- 类似java中的foreach语法。
for(NSString *str in array1){
NSLog(@"%@",str);
}
- 类似java的lambdk语法
- (void)enumerateObjectsUsingBlock:(void (^)(id obj,NSUInteger idx,BOOL *stop))block;
[array enumerateObjectsUsingBlock:^(NSString *string,NSUInetger index,BOOL *stop){
NSLog(@"%@",string);
}]
NSDictionary
是不可变的。用于存放key-value对。相当于不可变的HashMap,但是java中的HashMap必须使用泛型。而OC中的NSDictionary中的key-value对的类型相当于都是id。所以可以存放所有类型的对象。使用的时候必须进行强制类型转换。
注意一点,NSDictionary也是通过Hash的方法存放数据,其时间复杂度为O(1),但是有一点不同,遇到hash碰撞的时候,java使用的是链表法,并且会在链表长度大于8时转换为红黑树。而OC中的解决方法为开放地址法。并且也会有扩容的行为。这一块暂时还没有阅读源码。明天进行学习。
创建一个字典
//注意是先value再key。
[NSDictionary dictionaryWithObjectsAndKeys:value1,@"v1",value2,@"v2",value3,@"v3", nil];
得到数值
- (id) objectForKey: (id)aKey;
[dictionary objectForKey:key1];
NSMutableDictionary
可变的HashMap。更像java中的HashMap。
创建一个可变字典
+ (id) dictionaryWithCapacity: (NSUInteger) numItems;
向可变字典中添加键值对
- (void)setObject:(id)anObject forKey:(id)aKey;
明天阅读NSDictionary的源码和NSMutableDictionary的源码,分析其和java中源码的区别。