我们都知道数组(Array)是有序的元素序列,而在某种程度上,数组又可以划分为动态数组和静态数组。动态数组是指在声明时没有确定数组大小的数组,即忽略圆括号中的下标;当要用它时,可随时用ReDim语句重新指出数组的大小。本文就来和大家一起来探讨动态数组的相关知识。
Objective-C中的NSMutableArray就是一个动态数组,不用指定数组的长度就可以放心向里边添加元素,不需要考虑溢出的问题。实现动态数据的方式非常多,例如对静态数组进行封装扩容或者链表,甚至多种方式混合使用,根据数据量的大小来动态改变自己的数据结构。这里就使用最简单的根据静态数据动态扩容的方式,来实现一个动态数组。
为了实现一套完整的自定义数据结构,这里对静态数组的封装,使用的是之前自定义静态数组,因为Objective-C并没有封装好的静态数组可用,实际上就是一个可以存放指针并且内部维持Objective-C引用计数的指针数组。
自定义动态数组的效果
JKRArrayList *array = [JKRArrayList new];
for (NSUInteger i = 0; i < 60; i++) {
[array addObject:[Person personWithAge:i]];
}
NSLog(@"添加后 %@", array);
打印:
--- 扩容: 16 -> 24 ---
--- 扩容: 24 -> 36 ---
--- 扩容: 36 -> 54 ---
--- 扩容: 54 -> 81 ---
添加后 size=60, {
...
}
[array removeAllObjects];
NSLog(@"清空后 %@", array);
打印:
...
清空后 size=0, {
}
上面说的是动态数组的具体实现,下面我们一起来看动态数组的基本功能。
动态数组的应该提供的功能仿照NSMutableArray来设计,由于之后还会用多种链表来实现动态数组,所以还会有很多相同的处理逻辑和接口,这里先定义一个动态数组的基类:
@interface JKRBaseList
@protected
// 记录动态数组的当前长度
NSUInteger _size;
}
- (NSUInteger)count;
- (void)rangeCheckForAdd:(NSUInteger)index;
- (void)rangeCheckForExceptAdd:(NSUInteger)index;
- (void)addObject:(nullable ObjectType)anObject;
- (BOOL)containsObject:(nullable ObjectType)anObject;
- (nullable ObjectType)firstObject;
- (nullable ObjectType)lastObject;
- (void)removeFirstObject;
- (void)removeLastObject;
- (void)removeObject:(nullable ObjectType)anObject;
- (_Nullable ObjectType)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(_Nullable ObjectType)obj atIndexedSubscript:(NSUInteger)idx;
@end
@interface JKRBaseList
- (void)insertObject:(nullable ObjectType)anObject atIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(nullable ObjectType)anObject;
- (nullable ObjectType)objectAtIndex:(NSUInteger)index;
- (NSUInteger)indexOfObject:(nullable ObjectType)anObject;
- (void)removeAllObjects;
- (void)enumerateObjectsUsingBlock:(void (^)(_Nullable ObjectType obj, NSUInteger idx, BOOL *stop))block;
@end
JKRBaseList是所有动态数组的基类,之所以有一部分在扩展里边写,是为了便于区分,扩展内的接口是需要子类实现的,而扩展之外的接口则是不同方式实现的动态数组都相同的处理,不需要子类重写,只要JKRBaseList自己实现即可。把不需要JKRBaseList实现的方法写在扩展的好处就是不需要在JKRBaseList.m里边写接口的具体实现,如果定义成它的方法声明而不去实现的话,编译器会报警告。另外分成两部分写,也便于区分哪些是子类需要实现的。
系统的NSArray和NSMutableArray都允许存放nil,这里为了扩容功能,所以允许传入并保存nil到数据中。
首先先看一下JKRBaseList里边的成员变量:NSUInteger _size; 这个变量是所有动态数组都需要的,它负责记录当前动态数组的长度。因为动态数组对外部可见的长度和内部真实的长度是不一定一致的,比如现在我们要实现的通过静态数组封装的动态数组,刚刚开始初始化的时候,动态数组对象内部保存的静态数组长度可能是16,而外部展示的长度则为0,因为还没有添加任何元素。如果用链表来实现动态数组的话,同样需要记录数组长度,否则每次都要遍历链表所有节点来累加计算数组长度。
以上就是我们对动态数组的实现和功能的简单介绍,实际上,动态数组可以在任何时候改变大小,在灵活、方便的同时也有助于有效管理内存。是不是已经感受到了动态数组的神奇和强大的能力了?其实,数组的魅力远不止如此,‘’欲穷千里目,更上一层楼。‘’,观看本站的Java零基础教程,领略更加奥妙的数组风情吧!
在学习java编程的时候,最重要的就是对java基础知识的学习,数组就是java基础知识中一员。今天这篇文章我们来学习java数组中多维数组用法,学习多维数组该怎样使用。
数组(Array)是有序的元素序列。在程序中可以使用下标变量,即说明这些变量的整体为数组,数组中的每个变量的数据类型是相同的。当数组中每个元素都只带有一个下标时,称这样的数组为一维数组。
对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。下面为大家介绍14种数组对象方法。
Java数组初始化详解
Java SE(Java Platform, Standard Edition,Java标准版),基础进阶
Java SE(Java Platform, Standard Edition,Java标准版),零基础入门
IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境,它所提倡的是智能编码,是减少程序员的工作
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目
Docker 是一个基于 Go 语言 并遵从 Apache2.0 协议开源的应用容器引擎,让开发者可以打包应用到一个可移植的镜像中
jQuery是一个快速、简洁的JavaScript框架
动力节点在线报名表(此信息已加密,请放心填写)