objective-c中常用数据结构的总结

572 阅读5分钟

objective-c中常用数据结构的总结

cocoa提供的结构体

  1. 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
  2. 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的原因之一。

快速枚举

  1. 类似java中的foreach语法。
for(NSString *str in array1){
	NSLog(@"%@",str);
}
  1. 类似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中源码的区别。