When is it better to use an NSSet over an NSArray?

我已经在我的应用程序中使用了很多次 NSSets,但是我自己从来没有创建过一个。

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

56953 次浏览

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

原因是集合使用散列值来查找项(如字典) ,而数组必须遍历其整个内容来查找特定对象。

The image from 苹果的文档 describes it very well:

Objective-C Collections

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]

最好的答案是 苹果自己的文档

enter image description here

主要区别在于,NSArray用于有序集合,而 NSSet用于无序集合。

There are several articles out there that talk about the difference in speed between the two, like 这个. If you're iterating through an unordered collection, NSSet is great. However, in many cases, you need to do things that only an NSArray can do, so you sacrifice the speed for those abilities.

NSSet

  • 通过比较主要访问项
  • 无序
  • 不允许重复

NSArray

  • 可以通过索引访问项目
  • Ordered
  • 允许复制

就是这样,如果有帮助就告诉我。

数组用于根据索引访问项。任何项都可以多次插入到数组中。数组保持其元素的顺序。

集合基本上只用于检查该项是否在集合中。这些项目没有顺序或索引的概念。集合中的项不能有两次。

如果一个数组想要检查它是否包含一个元素,它必须检查它的所有项。设置是为了使用更快的算法。

你可以想象一个没有值的字典集。

请注意,数组和集不是唯一的数据结构。还有其他的,例如 Queue,Stack,Heap,Fibonacci’s Heap。我建议读一本关于算法和数据结构的书。

有关更多信息,请参见 wikipedia

NSOrderedSet 在 iOS5 + 中是可用的,因此主要的区别在于您是否希望在数据结构中有重复的对象。

主要的分歧已经在其他答案中给出。

我只想指出,由于集合和字典的实现方式(即使用散列) ,应该注意不要使用可变对象作为键。

如果键发生了变化,那么散列(可能)也会发生变化,指向散列表中不同的索引/桶。原始值不会被删除,而且在枚举或询问结构的大小/计数时实际上会被考虑在内。

这可能会导致一些非常难以定位的错误。

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-0411:05:40.935[598:15730](1,2,3,4,2,1)

布景

2015-12-0411:05:43.362[598:15730]{(3,1,2,5)}

NSArray :

  1. 有序的数据收集
  2. 允许复制
  3. 它是集合类型对象

NSSet :

  1. Unordered collection of data
  2. Does not allow duplicates
  3. 它也是集合类型对象

在这里 ,您可以找到 NSArrayNSSet数据结构的相当全面的比较。

简短的结论:

是的,NSArray 在保持和迭代方面比 NSSet 更快。构造速度只快50% ,迭代速度快500% 。教训: 如果只需要迭代内容,则不要使用 NSSet。

当然,如果需要测试是否包含 NSArray,请努力避免使用 NSArray。即使您同时需要迭代和包含测试,您可能仍然应该选择 NSSet。如果需要保持集合的顺序并测试是否包含,那么应该考虑保持两个集合(NSArray 和 NSSet) ,每个集合包含相同的对象。

NSDictionary 的构建速度比 NSMapTable 慢ーー因为它需要复制关键数据。它通过更快的查找来弥补这一点。当然,两者有不同的能力,所以大多数时候,这个决定应该在其他因素上做出。

通常使用 当访问速度至关重要且顺序无关紧要时设置,或者通过其他方式(通过谓词或排序描述符)确定。例如,当通过对多关系访问托管对象时,CoreData 使用集

只是添加一点它,我使用 set 有时只是为了删除重复数组,如:-

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values