一、数组是实例的有序集合,在Foundation框架中定义为NSArray类。
1. NSArray的基本介绍
NSArray是OC中使用的数组,是面向对象的,以面向对象的形式操纵对象,是不可变数组。
C语言数组有一个缺点即数组中只能存放同种数据类型的元素。
OC数组只能存放OC对象,不能存放非OC对象,如int,结构体和枚举等。(也就是集合中不能存放基本数据类型,要是一定要使用的话,只有将基本数据类型包装成对象在放入集合中使用)--- 更多资料在 Foundation框架—NSNumber博文中
2. NSArray的创建
void arrayCreat() {
// 普通数组的创建
int a = 5;
int ages[10] = {1, 2, 3, 4, 5};
// 创建一个Student对象的数组
Student *stu = [[Student alloc] init];
Student *s[5] = {stu, [[Student alloc] init]};
// 创建一个空数组(静态方法创建);不可变数组
NSArray *array = [NSArray array];
NSArray *array2 = [NSArray array];
// 创建一个元素的数组, 这个数组只用一个元素,且永远只用一个
array = [NSArray arrayWithObject:@"123"];
// 创建多个元素的数组, nil是数组结束的标记,在数组中不能使用nil就是这个原因
array2 = [NSArray arrayWithObjects:@"a", @"b", nil];
}
1). NSArray的访问
// 数组的访问
NSUInteger count = [array count];
NSLog(@"长度是%zi", count);
// 是否包含某个元素
if ([array containsObject:@"123"]) {
NSLog(@"包含了字符串a");
} else {
NSLog(@"没有包含了字符串a");
}
3. NSArray的遍历
#pragma mark 遍历数组
void arrayFor() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
// 快速遍历
int i = 0;
for (id obj in array) { // 类似于java中的for(int x :arr)
NSLog(@"快速遍历 %i-%@", i, obj);
i++;
}
}
// 遍历方式2
void arrayFor1() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
NSUInteger count = array.count;
for (int i = 0; i < count; i++) {
id obj = [array objectAtIndex:i];
NSLog(@"获取遍历 %zi-%@", i, obj);
}
}
// 遍历方式三
void arrayFor2() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
// void (^myBlock)(id, NSUInteger, BOOL) = ^(id obj, NSUInteger idx, BOOL *stop) ;
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"块遍历 %zi-%@", idx, obj);
// 设置停止遍历的位置
if (idx == 1) {
// 利用指针修改外边BOOL变量的值,外面的bool变量是看不见的,只有外面的bool变量才能停止遍历
*stop = YES; //
}
}];
}
// 遍历方式四
void arrayFor3() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
// 获取数组迭代器
NSEnumerator *enumerator = [array objectEnumerator];
// 获取下一个需要遍历的元素
id obj = nil;
while (obj = [enumerator nextObject]) {
NSLog(@"迭代器遍历 obj = %@", obj);
}
//反序迭代器(就是从尾部开始遍历)
enumerator = [array reverseObjectEnumerator];
// 获取下一个需要遍历的元素
obj = nil;
while (obj = [enumerator nextObject]) {
NSLog(@"反序迭代器遍历 obj = %@", obj);
}
}
4. 派生出新的数组
void arrayNew() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
NSArray *array1 = [array arrayByAddingObject:@"4"];
NSArray *array2 = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"4", @"5", nil]];
NSLog(@"array: %@", array);
NSLog(@"array1: %@", array1);
NSLog(@"array2: %@", array2);
// 从指定位置截取派生新的数组
NSArray *array3 = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];
NSRange range = NSMakeRange(1, 2);
NSArray *array4 = [array3 subarrayWithRange:range];
NSLog(@"array4: %@", array4);
}
5. 数组的其他用法 截取分割
void arrarOther() {
NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];
// 利用分隔符拼接所有元素,将字符串数组组合成字符串
NSString *str = [array componentsJoinedByString:@"-"];
// 将字符串变成字符创数组
NSArray *array1 = [str componentsSeparatedByString:@","];
NSLog(@"%@", str);
NSLog(@"%@", array1);
}
6. 数组的排序
// 数组排序
void arraySort() {
NSArray *array = [NSArray arrayWithObjects:@"11", @"2", @"32", @"4", nil];
// 返回一个排好序的数组,原来数组的元素顺序不会改变
NSArray *array1 = [array sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"%@", array1);
}
// 数组排序2 复杂
void arraySort1() {
Student *stu1 = [Student studentWithFirstName:@"zhong" andLastName:@"ye"];
Student *stu2 = [Student studentWithFirstName:@"zhang" andLastName:@"xi"];
Student *stu3 = [Student studentWithFirstName:@"chen" andLastName:@"hai"];
Student *stu4 = [Student studentWithFirstName:@"liu" andLastName:@"dong"];
// 当数组被销毁是,里面的所有元素会做一次 release操作
NSArray *array = [NSArray arrayWithObjects:stu1, stu2, stu3, stu4, nil];
NSArray *array2 = [array sortedArrayUsingSelector:@selector(compareStudent:)];
NSLog(@"array2 %@", array2);
}
二、NSMutableArray 可变数组
1. NSMutableArray的基本使用
注意:NSMutableArray继承自NSArray,几乎拥有NSArray的一切方法。
void kebian() {
// 创建一个可变数组
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"nihao", @"haoa", nil];
// 添加元素
// 添加一个student对象
[array addObject:[[Student alloc] init]];
// 添加一个字符串对象
[array addObject:@"nihaome"];
// 注意oc中的字符串不能是空nil
// 下面是错误的
[array addObject:nil];
// 删除元素
// 删除所有元素
[array removeAllObjects];
// 删除指定元素
[array removeObject:@"nihao"];
// 删除指定元素的对象
[array removeObjectAtIndex:0];
NSLog(@"%@", array);
NSLog(@"%ld", array.count);
}
三、NSSet和NSMutableSet 不可变集合与可变集合
无序集合(简称集合)与数组不同,他是没有先后顺序的。集合的优势在于,它保证每个集合成员唯一性,因此当判断某个实例是否位于集合中时,或是判断某个集合是否是另一个集合的子集时,集合的效率要远高于数组。
集合在很多方面与数组很类似。集合也分为不可修改的NSSet类与可修改的NSSet类。
1. 不可变集合NSSet 基本使用
void jihe() {
// 创建一个NSSet
NSSet *S = [NSSet set];
NSLog(@"%@", S);
// 因为不可变,所以set永远为空
// 创建一个有多个元素的NSSet
NSSet *s = [NSSet setWithObjects:@"nihao", @"shia", nil];
NSSet *s1 = [NSSet setWithObjects:@"nihao", @"shia", nil];
NSSet *s2 = [NSSet setWithObjects:@"nihao", @"shia", @"nihaoa", nil];
// 比较两个集合是否存在交集
BOOL result = [s intersectsSet:s1];
NSLog(@"s intersectsSet:s1 : %@", [s intersectsSet:s1]? @"YES":@"NO"); // 方法与下面效果类似
NSLog(@"s intersectsSet:s1: %i", result);
// 比较两个几个是否存在包含关系 后者是否包含前者
BOOL result1 = [s2 isSubsetOfSet:s1];
NSLog(@"s intersectsSet:s2: %i", result1);
// 比较两集合是否完全相等
BOOL result2 = [s isEqualToSet:s1];
NSLog(@"s intersectsSet:s2: %i", result2);
// 比较两个集合是否完全相等
// 随机取出一个
NSString *str = [s anyObject];
NSLog(@"%@", str);
}
2. 可变集合NSMutableSet
void jihe2() {
// 创建一个NSMutableSet
NSMutableSet *s = [NSMutableSet set];
// 添加元素
[s addObject:@"nihaome"];
// 删除元素
// 删除指定元素
[s removeObject:@"nihaome"];
}
3. 可变与不可变的对比
1)共同点:
1)都是集合,都能够存放多个对象
2)只能存放oc对象,不能存放非oc对象类型(如int等基本数据类型和结构体,枚举等)。
3)本身都不可变,都有一个可变的子类。
2)不同点:
1)NSArray有顺序,NSSet没有顺序
四、NSDictionary 与 NSMutableDictionary
1.不可变字典
1). 介绍现实中的字典:根据索引找到具体的内容
OC中的NSDictionary:根据key找到value。里面存储的东西都是键值对。
2). 字典的创建
void dictCreat() {
// NSDictionary 是不可变的
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"you" forKey:@"i love"];
NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
@"you", @"i love",
@"you", @"love", nil]; // 切记键值对不能是一样的,不然只会输出其中一个
NSLog(@"dict %@", dict);
NSLog(@"dict1 %@", dict1);
NSArray *objects = [NSArray arrayWithObjects:@"a1", @"a2", @"a3", nil];
NSArray *keys = [NSArray arrayWithObjects:@"b1", @"b2", @"b3", nil];
dict1 = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSLog(@"dict2 %@", dict1);
}
3). 字典的访问
void dictOther() {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"a1", @"k1",
@"a2", @"k2",
@"a3", @"k3", nil];
// 计算键值对对数
NSLog(@"count = %zi", dict.count);
// 由于NSDictionary是不可变的,所以只能取值,而不能修改值
id obj = [dict objectForKey:@"a2"];
NSLog(@"obj = %@", obj);
// 将字典写入文件中
// atomicall 原子行 就是当文件写入成功后在进行创建
NSString *path = @"/Users/shumei/Desktop/test.xml";
[dict writeToFile:path atomically:YES];
// 从文件中读取内容
dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"dict = %@", dict);
}
void dictUse() {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"a1", @"k1",
@"a2", @"k2",
@"a3", @"k3", nil];
// 返回所有的key
NSArray *keys = [dict allKeys];
NSLog(@"keys = %@", keys);
NSArray *objects = [dict allValues];
NSLog(@"objects = %@", objects);
// 跟库多个key取出对应的多个value
// 当key找不到对应的value时候,用mark参数代替
objects = [dict objectsForKeys:[NSArray arrayWithObjects:@"k1", @"k2", @"k3", nil] notFoundMarker:@"not-fount"];
NSLog(@"objects = %@", objects);
}
4). 字典的遍历
// 遍历字典 迭代器
void dictFor1() {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"a1", @"k1",
@"a2", @"k2",
@"a3", @"k3", nil];
// 遍历字典的所有key
NSEnumerator *enumer = [dict keyEnumerator];
id key = nil;
while (key = [enumer nextObject]) {
id value = [dict objectForKey:key];
NSLog(@"%@ = %@", key, value);
}
}
// 遍历字典 代码块
void dictFor2() {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"a1", @"k1",
@"a2", @"k2",
@"a3", @"k3", nil];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"%@ = %@", key, obj);
}];
}
2. 可变字典
注意:这种快速创建的方式只适用于不可变字典。