搜索
您的当前位置:首页正文

集合类型

来源:知库网

认识数组
1)数组是一个有序的元素序列,支持随机存储。索引从0开始,索引访问越界会抛出运行时异常。注意与C语言数组不同。
----------------NSArray初始化------------

    //工厂方法 最后放nil 表示结束 它不是元素
    NSArray *array1=[NSArray arrayWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];
    //内存分配alloc+init初始化
    NSArray *array2=[[NSArray alloc] initWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];
    //使用字面常量 不需要Nil
    NSArray *array3=@[@"Shanghai",@"Beijing",@"New York",@"Paris"];
    
    NSLog(@"array1 count: %lu" ,array1.count);//4
    NSLog(@"array2 count: %lu" ,array2.count);//4
    NSLog(@"array3 count: %lu" ,array3.count);//4
    NSLog(@"array1: %@" ,array1);//按字符串方式打印出来

2)NSArray被定义为class,引用类型,拷贝时具有引用语义。
3)NSArray的元素必须是对象,即NSObject的子类:
*如为基本数据类型,需要用NSNumber封装为对象类型后,才能放入数组里面。
*如果为C语言结构类型,需要用NSValue封装为对象类型后,才能放入数组中。
*数组元素可以是不同对象类型,可能会有类型不安全。(取值的时候不清楚是什么类型)
//----------------数组元素-------------

 NSString *text=@"Panda";//字符串对象
    NSInteger number=100;//不是对象 是从新定义后的整数 基于cpu架构 还是值类型
    NSNumber *numberObject1=
        [NSNumber numberWithInteger:number ];//使用NSNumber将NSInteger包装为对象
    NSNumber *numberObject2=@300u;//使用字面常量初始化
    Point point;//结构类型也不行 需要使用NSValue将struct包装为对象 编码方式将Point写进去
    point.h=100;
    point.v=200;
    NSValue *pointObject=
        [NSValue value:&point withObjCType:@encode(Point)];//使用NSValue将struct包装为对象
    NSNull* nullValue=[NSNull null];
    NSArray *array4=@[text, numberObject1,numberObject2,pointObject, nullValue];
    NSLog(@"array4: %@" ,array4);

4)NSArray具有常量性:长度和元素指针都不能更改。但指针指向的对象内部可以更改。
//----------------数组的常量性-------------

BLNPoint *p1=[[BLNPoint alloc] initWithX:10 WithY:20];
BLNPoint *p2=[[BLNPoint alloc] initWithX:20 WithY:40];
BLNPoint *p3=[[BLNPoint alloc] initWithX:30 WithY:60];
BLNPoint *p4=[[BLNPoint alloc] initWithX:40 WithY:80];
    
NSArray *array5=@[p1,p2,p3,p4];
    
NSLog(@"array5: %@", array5);
    
BLNPoint *p5=[[BLNPoint alloc] initWithX:50 WithY:100];
    
//1. 更改元素长度-----不可以!
//[array5 addObject:p5];
    
//2. 更改元素指针-----不可以!
//array5[0]=p5;
    
//3. 更改指针指向的内容-----可以!
    for(int i=0;i<array5.count;i++){
        BLNPoint *pt= array5[i];//取出每个元素
        pt.x++;//将指针里面指向的内容更改
        pt.y++;
    }
    NSLog(@"array5: %@", array5);

数组的常用操作:
//----------------数组的遍历-------------
最快-Fast Enumeration,直接访问内存,优化索引检查,快5-10倍 建议用这种

//快速枚举 如果不知道类型 用id 或者 object
    for ( BLNPoint* point in array5)
    {
        point.x++;
        point.y++;
    }

较慢-NSEnumerator遍历 索引检查+动态消息调用

//迭代器模式
    NSEnumerator *enumerator = [array5 objectEnumerator];
    BLNPoint* item;
    while (item = [enumerator nextObject])//消息分发
    {
        item.x++;
        item.y++;
    }

最慢-For循环访问:索引检查+动态消息调用

//for循环
    for (int i=0; i<array5.count; i++) {
        NSLog(@"array5[%d],%@",i,array5[i]);//访问索引
    }

数组查找
1)indexofobject查找是否存在“值相等”的对象(类型需要实现isEqual)
2)indexofobjectIdenticalTo 查找是否存在“指针相等”的对象

//数组查找
    BLNPoint* target=[[BLNPoint alloc] initWithX:33 WithY:63];
    NSUInteger index1=[array5 indexOfObject:target];//查找值是否相等
    NSUInteger index2=[array5 indexOfObjectIdenticalTo:p3];//指针引用是否相等
    
    NSLog(@"find at %lu", index1);//find at 2
    NSLog(@"find at %lu", index2);//find at 2

在进行查找值是否相等的时候 需要写这个方法:

- (BOOL)isEqual:(id)anObject{
    
    if (! [anObject isKindOfClass: [BLNPoint class]] ){
        return false;
    }
    
    BLNPoint* other=anObject;
    return (self.x==other.x && self.y==other.y);
  
}

数组排序
不改变原数组(常量性),返回新数组

 //数组排序 字母排序 不更改里面的内容 取返回值给新的数组
    NSArray* sortArray1=[array1 sortedArrayUsingSelector:@selector(compare:)];
    NSLog(@"array1: %@" ,array1);
    NSLog(@"sortArray1: %@" ,sortArray1);
结果:
array1: (
    Shanghai,
    Beijing,
    "New York",
    Paris
)
sortArray1: (
    Beijing,
    "New York",
    Paris,
    Shanghai
)

使用NSMutableArray
NSMutableArray支持更改数组长度和元素指针。为NSArray的子类。

//初始化
    NSMutableArray   *muArray1=[NSMutableArray arrayWithObjects:p1,p2,p3,p4, nil];
    
    NSLog(@"before change, muArray1: %@",muArray1);
    
    BLNPoint *p6=[[BLNPoint alloc] initWithX:60 WithY:120];
    BLNPoint *p7=[[BLNPoint alloc] initWithX:70 WithY:140];
    
    //修改元素
    [muArray1 addObject:p5];//增加一个元素
    [muArray1 removeObjectAtIndex:2];//将p3元素删除
    [muArray1 insertObject:p6 atIndex:1];//在1位置上插入p6
    muArray1[0]=p7;  //[muArray1 setObject:p7 atIndexedSubscript:0];
    NSLog(@"after change, muArray1: %@",muArray1);

NSMutableArray初始化后,会分配一个缓存容量capacity,一般大于实际元素数量,当长度增长时,如实际需求大于capacity会以近似2倍的方法指数增长。伴随代价:
分配新的堆内存2capacity
*将原来堆内存上的元素拷贝到新的内存
*释放原来的堆内存

 //预估容量
    int count=100;
    NSMutableArray *muArray2=[NSMutableArray arrayWithCapacity:10];
    
    for (int i=0; i< count; i++) {
        BLNPoint *pt=[[BLNPoint alloc] initWithX:i*10 WithY:i*20];
        [muArray2 addObject: pt];
    }

最佳实践:估计好capacity,预先分配一定容量,避免以后增长。
尽量避免使用insertObject:atIndex:和removeObjectAtIndex操作,因为会改变数组元素序列,涉及大量内存拷贝操作,代价高。前移后移的操作。
认识NSSet集合(无序)
NSSet是一个无序的集合,其存储的对象不能重复。
NSSet被定义为class,引用类型,拷贝时具有引用语义。
常量集合NSSet,可变集合:NSMutableSet:
常量性:长度和指针元素都不能更改。但指针指向的对象内部可以更改。
创建NSMutableSet时用initwithcapacity提前设置capacity
支持Fast Enumeration和NSEnumerator变量,前者较快。

void setDemo()
{
    
    //---------------- NSSet 与 NSMutableSet-------------
    //初始化
    NSSet *set1 =
        [NSSet setWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];
    NSLog(@"set1 count: %lu", set1.count);
    
    NSMutableSet *set2 =
        [NSMutableSet setWithObjects:@"Shanghai",@"Beijing",@"New York",@"Paris", nil];

    [set2 addObject:@"London"];
    [set2 addObject:@"Paris"];
    [set2 removeObject:@"Beijing"];
    NSLog(@"set2 count: %lu", set2.count);
    
    //判断是否包含某个对象
    if([set2 containsObject:@"Shanghai"])
    {
        NSLog(@"set2 contains Shanghai");
    }
    //遍历
    for(NSString* item in set2)
    {
        NSLog(@"%@", item);
    }

}

认识字典NSDictionary
NSDictionary是一个存储key-value的无序集合,key唯一,value可重复。
NSDictionary被定义为class,引用类型,拷贝时具有引用语义。
常量集合NSDictionary,可变集合:NSMutableDictionary:
常量性:长度和指针元素都不能更改。但指针指向的对象内部可以更改。
创建NSMutableDictionary时用initwithcapacity提前设置capacity
支持Fast Enumeration和NSEnumerator变量,前者较快。

void dictionaryDemo()
{
    //---------------- NSDictionary 与 NSMutableDictionary-------------
    
    BLNPoint *p1=[[BLNPoint alloc] initWithX:10 WithY:20];
    BLNPoint *p2=[[BLNPoint alloc] initWithX:20 WithY:40];
    BLNPoint *p3=[[BLNPoint alloc] initWithX:30 WithY:60];
    BLNPoint *p4=[[BLNPoint alloc] initWithX:40 WithY:80];
    BLNPoint *p5=[[BLNPoint alloc] initWithX:50 WithY:100];
    
    //@{key:value}
    NSDictionary *dictionary1 = @{
                                  @"Shanghai" : p1,
                                  @"Beijing" : p2,
                                  @"New York" : p3,
                                  @"Paris" : p4};
    //[value,key ,nil结束]
    NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                p1,@"Shanghai",
                                p2,@"Beijing",
                                p3,@"New York",
                                p4,@"Paris",
                                nil];
    
   
    NSLog(@"dictionary1 count: %lu", dictionary1.count);
    NSLog(@"dictionary2 count: %lu", dictionary2.count);
    
    BLNPoint* result1=[dictionary1 objectForKey:@"Beijing"];//查value是什么
    BLNPoint* result2=dictionary1[@"Shanghai"];
    NSLog(@"%@", result1);
    NSLog(@"%@", result2);
    
    for(NSString* key in dictionary1)
    {
        id object=dictionary1[key];
        NSLog(@"key:%@, object:%@", key, object);
    }
    
    
    [dictionary2 setObject:p5 forKey:@"London"];
    [dictionary2 removeObjectForKey:@"Shanghai"];
    NSLog(@"dictionary2: %@", dictionary2);
    
}
Top