什么时候使用NSSet比NSArray更好?
我在我的应用中多次使用NSSets,但从未创build过一个。
我的问题是:
什么时候使用NSSet
而不是NSArray
更好?为什么?
当集合中的项目顺序不重要时,集合可以提供更好的查找集合中项目的性能。
原因是一个集合使用散列值来查找项目(如字典),而数组必须迭代整个内容才能find特定的对象。
苹果文档的图片描述得非常好:
Array
是一个有序的 (当你添加时保持顺序)元素序列
[array addObject:@1]; [array addObject:@2]; [array addObject:@3]; [array addObject:@4]; [array addObject:@6]; [array addObject:@4]; [array addObject:@1]; [array addObject:@2]; [1, 2, 3, 4, 6, 4, 1, 2]
Set
是一个独特的 (没有重复的), 无序的元素列表
[set addObject:@1]; [set addObject:@2]; [set addObject:@3]; [set addObject:@4]; [set addObject:@6]; [set addObject:@4]; [set addObject:@1]; [set addObject:@2]; [1, 2, 6, 4, 3]
最好的答案是这是苹果自己的文档 。
主要区别在于NSArray
用于有序集合,而NSSet
用于无序集合。
那里有几篇文章谈论两者之间的速度差异,就像这个 。 如果你正在迭代一个无序的集合, NSSet
是伟大的。 但是,在许多情况下,你需要做的只有NSArray
才能做的事情,所以你牺牲了这些能力的速度。
的NSSet
- 主要通过比较访问项目
- 无序
- 不允许重复
NSArray的
- 可以通过索引访问项目
- 有序
- 允许重复
这就是真的! 让我知道如果有帮助。
NSOrderedSet在iOS 5+中可用,所以主要区别在于是否需要数据结构中的重复对象。
NSArray :
- 有序的数据收集
- 允许重复
- 它是集合types的对象
NSSet :
- 无序的数据收集
- 不允许重复
- 这也是集合types对象
数组用于通过索引访问项目。 任何项目都可以插入到数组中多次。 数组维护其元素的顺序。
一个集合基本上只用于检查项目是否在集合中。 这些项目没有秩序或索引的概念。 你不能在一个集合中的项目两次。
如果一个数组想要检查它是否包含一个元素,它必须检查它的所有项目。 集合旨在使用更快的algorithm。
你可以想像一个像没有值的字典集。
请注意,数组和集合不是唯一的数据结构。 还有其他的,例如Queue,Stack,Heap,Fibonacci's Heap。 我会推荐读一本关于algorithm和数据结构的书。
请参阅维基百科获取更多信息。
其他答案已经给出了主要的区别。
我只想指出,由于集合和字典的实现方式(即使用散列),人们应该小心不要使用可变对象的键。
如果某个键发生了变化,则散列表(可能)也会发生改变,指向散列表中不同的索引/存储桶。 当枚举或询问结构的大小/数量时,原始值不会被删除,实际上会被考虑在内。
这可能会导致一些真正难以find错误。
NSArray *Arr; NSSet *Nset; Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil]; Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil]; NSLog(@"%@",Arr); NSLog(@"%@",Nset);
数组
2015-12-04 11:05:40.935 [598:15730](1,2,3,4,2,1)
集合
2015-12-04 11:05:43.362 [598:15730] {(3,1,2,5)}
在这里你可以findNSArray
和NSSet
结构的一个非常彻底的比较。
简短的结论:
是的,NSArray比NSSet更简单地持有和迭代。 构build速度快50%,迭代速度快500%。 课程:如果您只需要迭代内容,请不要使用NSSet。
当然,如果你需要testing包含,努力避免NSArray。 即使你需要迭代和包含testing,你也应该select一个NSSet。 如果你需要保持你的集合有序并且testing包含,那么你应该考虑保留两个集合(一个NSArray和一个NSSet),每个集合包含相同的对象。
NSDictionary比NSMapTable构造要慢 – 因为它需要复制关键数据。 它通过查找更快来弥补这一点。 当然,这两者在大多数时候都有不同的能力,这个决心应该是在其他因素上作出的。
当访问速度是本质的,顺序无关紧要时,通常使用一个集合,或者通过其他方法(通过谓词或sorting描述符)来确定。 核心数据例如在托pipe对象通过多对多关系访问时使用集合