Day5 oc 数据结构之Foundation字符串,数组,字典

oc数据结构

(摘自千峰学院课程及http://www.jianshu.com/p/34bba09c95d4,以后我的原创产品也搬到简书喽)

  • oc兼容c语言,自然兼容c的所有数据结构
  • oc特有数据结构


NSString:不可变字符串

//字符串的创建,创建以后内容将不可改变
#import <Foundation/Foundation.h>
int main (int argc,const char* argv[])
{
    @autoreleasepool{
    char* p = "hello world";//首先,oc完全兼容c语言的字符串语法
     //strlen(p);计算/0前字符长度,中文占3个字符
    NSLog(@"%s",p);    
    //4种创建字符串的方法
    NSString* str1 = @"hello world";//字符串对象
    //[str1 length]算的是字数,中文算一个字数

    NSString* str2 = [[NSString alloc]initWithString:str];//用一个字符串创建另一个字符串

    NSString* str3 = [[NSString alloc]initWithUTF8String:"hello world"];//用c的字符串来创建一个oc的字符串对象,c字符串转为oc字符串
    //const char *c = [str3 UTF8String];oc字符串转c
    NSString *s = [[NSString alloc] initWithContentsOfFile:@"/Users/test.txt" encoding:NSUTF8StringEncoding error:nil];//文件,也可写为
    NSURL *url = [[NSURL alloc] init] initWithString:@"file:///Users/test.txt";
    NSString *s1 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

    NSString* str4 = [[NSString alloc]initWithFormat:@"hello %d %c",5,'C'];//使用格式符拼接成一个字符串对象

    NSLog(@"%@",str1);
    NSLog(@"%@",str2);
    NSLog(@"%@",str3);
    NSLog(@"%@",str4);
    //直接调用类方法,NSString类方法以string开头
    NSString* str5 = [NSString stringWithString:str];

    NSString* str6 = [NSString stringWithUTF8String:"hello world"];

    NSString* str7 = [NSString stringWithFormat:@"%d %@ %c",1,@"hello",'C'];

    NSLog(@"%@",str5);
    NSLog(@"%@",str6);
    NSLog(@"%@",str7);
    [str3 release];//alloc创建需释放内存,由于ARC,所以可不写
    [str2 release];
    [str1 release];
    }
    return 0;
}

 

 
//字符串的比较
#import <Foundation/Foundation.h>
int main (int argc,const char* argv[])
{
    @autoreleasepool{
    NSString str1 = @"123";
    NSString str2 = @"456";

    BOOL res = [str1 isEqualToString:str2];//比较两个字符串内容是否相同
    NSLog(@"%d",ret);

    NSComparisonResult ret = [str1 compare:str2];//按字母表顺序比较
    //NSComparisonResult返回值是一个枚举类型,NSOrderedAscending=-1,NSOrderedSame=0,NSOrdereDescending=1
    if(ret==NSOrderedAscending){
    NSLog(@"str1<str2");//结果
    }else if (ret==NSOrderedSame){
    NSLog(@"str1==str2");//123 和123 相等
    }else if (ret==NSOrdereDescending){
    NSLog(@"str1>str2");
    }
    return 0;
}
 
#import <Foundation/Foundation.h>
int main (int argc,const char* argv[])
{
    @autoreleasepool{
    //一个字符串中查找子串
    NSString* str = @"I am a so bad man";
    NSString* subStr=@"so";

    NSRange range = [str rangeOfString:subStr];//NSRange是一个结构体,一个属性是location,一个是length.
    NSLog(@"location:%lu,length:%lu",range.location,range.length);//结果为7
    //从一个字符串生成一个子串
    NSString str1 = @"0123456789";
    NSString str2 = [str1 substringToIndex:6];//从str中提取6(0-5从0开始数)个字符,生成新字符串,返回字符串地址
    NSString str3 = [str2 substringFromIndex:6];//从第7(6从0开始数)个字符提取到最后
    NSLog(@"str1");
    NSLog(@"str2");//012345
    NSLog(@"str3");//6789

    //NSRange range2 = {3,4};//location,length
    //NSString str4 = [str1 substringWithRange:range2];
    NSString str4 = [str1 substringWithRange:NSMakeRange(3,4)];
    NSLog(@"str4");//3456
    }
    return 0;
}

NSMutableString:可变字符串

继承自NSString,所以可以使用普通字符串的方法,并在NSString的基础上扩展了新的方法,4大类,增、删、改、查。

#import <Foundation/Foundation.h>
int main (int argc,const char* argv[])
{
    @autoreleasepool{
    //NSMutableString* str1 = @"hello world";//不可以这样使用

    //实际上可变字符串可以这样使用
    NSMutableString* str1 = [NSMutableString alloc]init];
    [str1 setString:@"Hello"];//设置可变字符串的内容
    [str1 setString:@"World"];//再次设置会覆盖掉原有的字符串,str1=@"world"

    //增
    [str1 appendString:@"123"];//追加字符串
    [str1 appendFormat:@"%c",'d'];

    [str1 insertString:@"XXXX" atIndex:4];//插入字符串
    //没有插入Format,但可以这样处理
    [str1 insertString:[NSString stringWithFormat:@"%d",-54]atIndex:7];

    //删
    NSLog(@"%@",str1);//用法见ps
    [str1 deleteCharactersInRange:NSMakeRange(3,5)];//删除一定范围内的字符,从第3个开始删除5个字符

    //改
    [str1 replaceCharactersInRange:NSMakeRange(3,2) withString:@"XXXXX"];//替换一个范围内的字符,替换的字符长度不受原范围长度的限制,从第3个替换2个字符

    }
    return 0;
}
ps:NSLog格式
 

NSArray不可变数组(有序)(NSArray,NSSet,NSDictionary是集合类)

NSArray (java中为ArrayList)

有序

快速创建(不可变):@[]

快速访问元素:数组名[i]

NSSet (java中为HashSet)

无序

NSDictionary (java中为HashMap)

无序

快速创建(不可变):@{key1:value1,key2:value2}

快速访问元素:字典名[key]

#import <Foundation/Foundation.h>
 int main (int argc,const char* argv[])
 {
    @autoreleasepool{
    NSArray *array1 = [NSArray array];//创建个空数组
    NSArray *array = [NSArray alloc]initWithObjects:@"one",@"two",@"three",nil];//数组中装着元素的地址,数组的元素可以是任意对象
    NSArray *array = [NSArray arrayWithObjects:@"one",@"two",nil];//最后一个nil结尾不能省,oc数组只能存放oc对象,不能存放非oc对象,也不能存放nil
    //或者NSArray *array = @["@one","@two"];
    //打印数组
    NSLog(@"%@",array);//打印调用重写的description方法
    //数组遍历,4种方法
    //枚举器法
    NSEnumerator* emumerator = [array objectEnumerator];//创建枚举器
    id obj;
    while(obj=[enumerator nextObject]){
        NSLog(@"%@",obj);
    }
    //快速枚举法
    for(id obj in array){
        NSLog(@"%@",obj);
        }
    //使用i值遍历
    NSInteger length = [array count];
    NSInteger i;
    for(i=0;i<length;i++){
        NSLog(@"%@",[array objectAtIndex:i]);
        //或者NSLog(@"%@",array[i]);(编译器特性)
        }
     }
    //block遍历数组,每遍历一个元素,就会调用一次block,会把当前元素和索引位置参数传给block
    [array enumerateObjectsUsingBlock:
    ^(id obj,NSUInteger idx,BOOL *stop){
         NSLog(@"%ld-%@",idx,obj);
         if(idx == 0){
             *stop = YES;//遍历一次即停止
         }
    }
    ];
    return 0;
 

NSMutableArray:可变数组

#import <Foundation/Foundation.h>
 int main (int argc,const char* argv[])
 {
    @autoreleasepool{
    //是Array的子类,因此父类的方法也可以调用
    NSMutableArray* array = [NSMutableArray alloc]init];
    [array addObject:@"one"];//增加元素
    [array addObject:@"two"];
    [array addObject:@"three"];
    [array addObject:@"four"];
    [array addObject:@"five"];
    [array removeObject:@"one"];//删除元素
    [array removeObjectAtIndex:1];
    [array exchangeObjectAtIndex:3 withObjectAtIndex:4];//交换元素的位置
    //同样进行遍历
    //使用枚举器正序遍历时修改数组内容会导致程序崩溃
    NSEnumerator* enumeratoe = [array objectEnumerator];
    id obj;
    while(obj=[enumerator nextObject]){
        [array removeLastObject];
        NSLog(@"%@",obj);
        }
     //使用枚举器逆序遍历的时候修改数组内容,不会导致程序崩溃

    NSEnumerator* enumeratoe = [array reverseObjectEnumerator];
    id obj;
    while(obj=[enumerator nextObject]){
        [array removeLastObject];
        NSLog(@"%@",obj);
        }
    //使用快速枚举法时仍然不能对数组个数和内容进行修改,即使是可变数组
    //使用i进行遍历时可以对可变数组进行修改
    }
   return 0;
}

NSMutableArray内存管理中的用法

NSMutableArray *array =[[NSMutableArray alloc] init];
for(int i=0;i<10;i++){
   Dog *dog = [[Dog alloc] init];
   [dog setId:i];
   [array addObject:dog];//array会对dog对象计数器加1
   [dog release];
}
for(Dog *d in array){
   NSLog(@"dog is %d",[d ID]);
}
[array release];

  

 数组和字符串的综合使用

//将一个字符串中的单词逆序,如何实现
 #import <Foundation/Foundation.h>
 int main (int argc,const char* argv[])
 {
     @autoreleasepool{
        NSString* str = @"I am a so bad man";
        NSArray* array = [str componentsSeparatedByString:@" "];//将字符串以空格进行分割后存到数组中
        NSMutableArray* mutableArray = [[NSMutableArray alloc]init];
        NSEnumerator* enumerator = [array reverseObjectEnumerator];//逆序遍历
        NSString* obj;
        while(obj = [enumerator nextObject]){
        [mutableArray addObject:obj];//mutableArray中就是逆序的
        }
        NSString* newStr = [mutableArray componentsJoinedByString:@" "];//将数组中的元素插入空格拼成新的字符串
        }
        NSLog(@"%@",mutableArray);
    }
    return 0;
 }
 

NSDictionary:字典(无序)

#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"one",@"1",@"two",@"2",@"three",@"3",nil];
      NSDictionary *dict = @{@"name":@"aaa",@"age":@"3"};//编译器新特性
      //字典中的元素都是以键值对的形式存储的
      //@"one"和@"1"组成了一个键值对
      //@"one"称为值(Value),@"1"称为键(Key)
      //键值对的值和键,都是任意的对象,但是键往往使用字符串
      //字典中存储对象的地址没有顺序,这是与数组的不同
      NSLog(@"%@",dict);//字典同样重写了description
      NSArray *keys = @[@"name",@"age"];
      NSArray *objects = @[@"aaa",@"3"];
      NSDictionary *dict = [NSDictionary dictionaryWithObjects forKeys:keys];

      //字典中也可以进行遍历,而且分为键的遍历和值的遍历
       NSEnumerator* enumerator = [dict keyEnumerator];//键遍历
       id obj;
       while(obj = [enumerator nextObject]){
           NSLog(@"%@",obj);
       }

       NSEnumerator* enumerator = [dict objectEnumerator];//值遍历
       id obj;//因为没有顺序,也就没有顺序遍历和逆序遍历
       while(obj = [enumerator nextObject]){
           NSLog(@"%@",obj);
       }
       NSString * str = [dict objectForKey:@"1"];//通过键找到值
       //快速遍历
       for(id obj in dict){
           NSLog(@"%@",obj);//遍历得到的是键,字典重要的左右就是迅速根据键找到值
           NSLog(@"%@",[dict objectForKey:obj]);
           //NSLog(@"%@",dict[obj]);简化方式
       }

      }
      return 0;
  }
 

NSMutableDictionary:可变字典,可以更改键值对

  #import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
      [dict setObject:@"one" forKey:@"1"];//添加
      [dict setObject:@"two" forKey:@"2"];
      [dict setObject:@"three" forKey:@"1"];//多次给一个key赋值,会覆盖之前的值,因此这里有两个键值对
      NSLog(@"%@",dict);
      [dict removeObjectForKey:@"1"];//删除
      }
      //遍历
      NSArray *keys = [dict allKeys];//返回的是无序的
      for(int i = 0;i < dict.count;i++)
      {
          NSString *key = keys[i];
          NSString *object = dict[key];
          NSLog(@"%@ = %@",key,object);
      }
      [dict enumerateKeysAndObjectsUsingBlock:^(id key,id obj,BOOL *stop){      NSLog(@"%@ = %@",key,obj);}];
      return 0;
   }
 

NSNumber

NSNumber的对象可以是任何的数字类型,整型,浮点型,字符型等基本数据类型,NSNumber是一个类簇(还有UIButton),作用是把基本数据类型变成对象
#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSNumber* intNumber = [NSNumber alloc]initWithInt:5];
      //NSNumber *intNumber = [NSNumber numberWithInt:5];使用类方法创建
      //NSDictionary *dict = @{@"name":@"aaa",@"age": intNumber};
      //可简写为NSDictionary *dict = @{@"name":@"aaa",@"age":@5};编译器特性
      //将基础数据类型包装成NSNumber,int a=5,包装后为@(a),
      //NSNumber *num = dict[@"age"];
      //int a = [num intValue];
      NSNumber* floatNumer = [[NSNumber alloc]initWithFloat:3.14f];
      NSNumber* doubleNumber = [[NSNumber alloc]initWithDouble:6.7];
      NSNumber* charNumber = [[NSNumber alloc]initWithChar:'A'];
      NSNumber* intNumber2 = [NSNumber numberWithInt:6];
      BOOL res =[intNumber isEqualToNumber:intNumber2];//可以比较两个数值是否相等
      
      //BOOL res =[intNumber isEqualToNumber:floatNumber];//两个NSNumber之间都可以比较
      NSLog(@"%d",res);

      NSLog(@"%d",[intNumber intValue]);//还原对应的数据
      NSLog(@"%f",[floatNumber floatValue]);
      NSLog(@"%f",[doubleNumber doubleValue]);
      NSLog(@"%c",[charNumber charValue]);

       //两个数据之间的比较
      if([intNumber compare:intNumber2]==NSOrderedAscending){
      NSLog(@"<");
      }else if([intNumber compare:intNumber2]==NSOrderedSame){
      NSLog(@"=");
      }else if([intNumber compare:intNumber2]==NSOrderedDescending){
      NSLog(@">");
      }
    }
      return 0;
  

NSSet:集合(无序 哈希表 散列算法 查找元素比数组更快)

和数组NSArray(有序)相似,只是有序和无序的区别,而且集合中的相同元素只能有一个

#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSSet* set = [[NSSet alloc]initWithObjects:@"one",@"two",@"three",@"four",@"five",nil];//若加一个@"one",则打印出来仍然只有一个one,相同元素只有一个
      NSLog(@"%@",set);//打印出来的无序
      //set[0];错误,因为是无序的
      NSLog(@"%lu",[set count]);

      BOOL res = [set containsObject:@"five"];//判断集合中是否含有某个元素

      NSSet* set2 = [[NSSet alloc]initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",nil];
      BOOL res = [set isEqualToSet:set2];//判断两个集合是否相同

      BOOL res = [set isSubsetOfSet:set2];//判断一个集合是否是另一个集合的子集合

      NSEnumberator* enumberator = [set objectEnumerator];
      id obj;
      while(obj = [enumerator nextObject]){
      NSLog(@"%@",obj);
      }

      //也可以使用数组中的元素创建一个集合
      NSArray* array = [[NSArray alloc]initWithObjects:@"one",@"two",@"three",@"four",@"five",nil];
      NSSet* set = [NSSet alloc]initWithArray:array];

      //也可以使用一个集合生成一个数组
      NSArray* array2 = [set allObjects];
      }
      return 0;
  }

NSMutableSet:可变集合(NSSet子集)

可以动态添加和删除元素,如果添加的元素有重复,实际上只保留一个
#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSMutableSet* set = [[NSMutableSet alloc]init];
      [set addObject:@"one"];
      [set addObject:@"two"];
      [set addObject:@"three"];
      [set addObject:@"four"];
      [set addObject:@"two"];//重复,只保留一个
      [set removeObject:@"three"];

      NSSet* set2 = [[NSSet alloc]initWithObjects:@"five",@"six",nil];

      [set unionSet:set2];//set2中的元素将被添加到set中

      [set minusSet:set2];//从set中减去set2
      }
      return 0;
  }
 

NSIndexSet:索引集合

是集合的一个变种,但并没有继承关系。可以通过index找到集合中的一个元素,insexSet中装的都是数字 
#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSIndexSet* indexSet = [[NSIndexSet alloc]initWithIndexesInRange:NSMakeRange(2,3)];//给一个范围,集合中就是范围中的全部数据,现在集合中的数据就是2、3、4.

      NSArray* array = [[NSArray alloc]initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",nil];
      //通过一个索引的集合,可以取得数组中的部分元素
      NSArray* newArray = [array objectsAtIndexes:indexSet];索引为2、3、4时,数组中对应的元素
      NSLog(@"%@",newArray);//newArray中的元素为@"three",@"four",@"five".
      }
      return 0;
  }

 NSValue

NSValue是NSNumber的父类,用于将结构体,指针等复杂数据类型,存储为对象。

NSNumber之所以能包装基本数据类型为对象,是因为继承了NSValue,NSValue可以包装所有数据类型为对象

CGPoint p = CGPointMake(1,1);
//将结构体转换为Value对象
NSValue *value = [NSValue valueWithPoint:p];
//将value转换为对应结构体
[value pointValue];
 
#import <Foundation/Foundation.h>
  //声明一个结构体类型
  struct sct{
  int a;
  int b;
  }sctt={4,5};

  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSValue* value = [[NSValue alloc]initWithBytes:&sctt objCType:@encode(struct sct)];//@encode将类型转换为一个字符串,用于区分不同的类型,每个类型生成的字符串是唯一的
      NSLog(@"%s",@encode(int));
      if(strcmp(value.objCType,@encode(struct sct))==0){
          NSLog(@"This is struct sct.");
         }
      struct sct newSctt;
      [value getValue:&newSctt];//将结构体的数据存到对象中
      NSLog(@"%d %d",newSctt.a,newSctt.b);

      char* p = (char*)0x1F;//有一个指针p,初始化为0X1F
      NSValue* value = [[NSValue alloc]initWithBytes:&p objCType:@encode(char*)];
      char* q;
      [value getValue:&q];
      NSLog(@"%p",q);//打印结果为0X1F.

      CGPoint point;
      CGSize size;
      CGRect rect;
      NSRange range;

      NSValue* pointValue = [NSValue valueWith:point];
      NSValue* sizeValue = [NSValue valueWith:size];
      NSValue* rectValue = [NSValue valueWith:rect];
      NSValue* rangeValue = [NSValue valueWithRange:NSMakeRange{3,4}];
      }
      return 0;
  }

NSData

NSData:用于将信息写入文件时转化为0、1字节流,NSData就用于存储字节流,类似于C语言中的buffer.
char buf[10];
#import <Foundation/Foundation.h>
  int main (int argc,const char* argv[])
  {
      @autoreleasepool{
      NSString* string = @"hello world";

      NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];//字符串存储为NSData对象中
      NSLog(@"%s",data.bytes);//可以打印出字符串

      NSString* newString = [NSString stringWithData:data encoding:NSUTF8StringEncoding];//NSData对象转化为字符串.
      NSLog(@"%@",newString);
      }
    
     NSDate *date1 = [NSDate date];//创建一个时间对象,0时区的时间
     NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
     formatter.dateFormatter = @"yyyy-MM-dd HH:mm:ss";//H:24小时制,h:12小时制
     NSString *str = [formatter stringFromDate:date];
     NSDate *date3 = [NSDate dateWithTimeInterval:5 sinDate:date1];timeInterval是秒
     return 0;
  }
 

猜你喜欢

转载自magicbird.iteye.com/blog/2281617