什么时候使用NSSet比NSArray更好?

我在我的应用中多次使用NSSets,但从未创build过一个。

我的问题是:

什么时候使用NSSet而不是NSArray更好?为什么?

当集合中的项目顺序不重要时,集合可以提供更好的查找集合中项目的性能。

原因是一个集合使用散列值来查找项目(如字典),而数组必须迭代整个内容才能find特定的对象。

苹果文档的图片描述得非常好:

Objective-C集合

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

  1. 有序的数据收集
  2. 允许重复
  3. 它是集合types的对象

NSSet

  1. 无序的数据收集
  2. 不允许重复
  3. 这也是集合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)}

在这里你可以findNSArrayNSSet结构的一个非常彻底的比较。

简短的结论:

是的,NSArray比NSSet更简单地持有和迭代。 构build速度快50%,迭代速度快500%。 课程:如果您只需要迭代内容,请不要使用NSSet。

当然,如果你需要testing包含,努力避免NSArray。 即使你需要迭代和包含testing,你也应该select一个NSSet。 如果你需要保持你的集合有序并且testing包含,那么你应该考虑保留两个集合(一个NSArray和一个NSSet),每个集合包含相同的对象。

NSDictionary比NSMapTable构造要慢 – 因为它需要复制关键数据。 它通过查找更快来弥补这一点。 当然,这两者在大多数时候都有不同的能力,这个决心应该是在其他因素上作出的。

当访问速度是本质的,顺序无关紧要时,通常使用一个集合,或者通过其他方法(通过谓词或sorting描述符)来确定。 核心数据例如在托pipe对象通过多对多关系访问时使用集合