Go数据结构之简单数组及其迭代器

一、简单数组实现

想要实现一个数组,首先需要明白,数组内需要什么方法

常见的有:

  1. 数组大小
  2. 获取数组元素
  3. 更改数组元素
  4. 清空数组
  5. 添加数组元素
  6. 格式化输出数组
  7. 等等........

既然是自定义数组,那么就要求可以存储多种多样的元素,例如:基础的数据类型,结构体,等等

面对这个要求,我们有两种方式,第一种是使用 interface{ }  , 第二种则是使用 泛型 T any  

1. 实现代码

这里我们使用第二种,话不多说,上代码:

package list

import (
	"errors"
	"fmt"
)

type List[T any] interface {
	Size() int
	Get(index int) (T, error)
	Set(index int, value T) error
	Insert(index int, value T) error
	Delete(index int) error
	Append(value T)
	Clear()
	String() string
    // 迭代器
	Iterator() Iterator[T]
}

type ArrayList[T any] struct {
	dataStore []T
	theSize   int
}

func NewArrayList[T any](capSize int) List[T] {
    if capSize <= 0 {
        capSize = 10
    }
	list := new(ArrayList[T])
	list.dataStore = make([]T, 0, capSize)
	list.theSize = 0
	// 后续还要加入扩缩容机制
	return list
}

func (a *ArrayList[T]) Size() int {
	return a.theSize
}

func (a *ArrayList[T]) Get(index int) (T, error) {
	if index < 0 || index >= a.theSize {
		var zero T
		return zero, errors.New("索引越界")
	}
	return a.dataStore[index], nil
}

func (a *ArrayList[T]) Set(index int, value T) error {
	if index < 0 || index >= a.theSize {
		return errors.New("该索引不存在")
	}
	a.dataStore[index] = value
	return nil
}

func (a *ArrayList[T]) Insert(index int, value T) error {
	if index < 0 || index >= a.theSize {
		return errors.New("该索引不存在")
	}
	// 扩容
	a.Expand()
	a.dataStore = a.dataStore[:a.theSize+1]
	for i := a.theSize; i > index; i-- {
		a.dataStore[i] = a.dataStore[i-1]
	}
	a.dataStore[index] = value
	a.theSize++
	return nil
}

// Expand 扩容
func (a *ArrayList[T]) Expand() {
	if a.theSize >= cap(a.dataStore) {
		// make中间参数若为0,则只是声明,不是实际已经给你开辟了这么多
		list := make([]T, a.theSize*2, a.theSize*2)
		copy(list, a.dataStore)
		a.dataStore = list
	}
}

func (a *ArrayList[T]) Delete(index int) error {
	if index < 0 || index >= a.theSize {
		return errors.New("该索引不存在")
	}
	a.dataStore = append(a.dataStore[:index], a.dataStore[index+1:]...)
	a.theSize--
	return nil
}

func (a *ArrayList[T]) Append(value T) {
	a.dataStore = append(a.dataStore, value)
	a.theSize++
}

func (a *ArrayList[T]) Clear() {
	a.dataStore = make([]T, 0, 10)
    a.theSize = 0
}

func (a *ArrayList[T]) String() string {
	return fmt.Sprint(a.dataStore)
}

2. 注意事项

  • 使用接口,防止用户直接使用我们 ArrayList 里的成员
  • 保持依赖注入的风格,让用户自己决定需要多大的容量。
  • 关于扩缩容机制,可以自己权衡,示例中默认选择2倍,如有需要可以使用字节,则机制更精准完善
  • 功能还可继续完善,例如格式化部分,判断部分等等

二、数组迭代器实现

迭代器的意思是:一种用于遍历集合(如数组、列表、集合、映射等)中元素的抽象工具或方法。

1. 实现代码

package list

import (
	"errors"
)

// Iterator 迭代器
type Iterator[T any] interface {
	HasNext() bool
	Next() (T, error)
	Remove()
	GetIndex() int
}

// Iterable 可迭代存放的接口
type Iterable[T any] interface {
	Iterator() Iterator[T]
}

// ArrayListIterator 制作一个数组迭代器,使用指针来遍历访问数组,更方便
type ArrayListIterator[T any] struct {
	list         *ArrayList[T]
	currentIndex int // 当前索引
}

func (a *ArrayList[T]) Iterator() Iterator[T] {
	it := new(ArrayListIterator[T])
	it.currentIndex = 0
	it.list = a
	return it
}

func (it *ArrayListIterator[T]) HasNext() bool {
	return it.currentIndex < it.list.theSize
}

func (it *ArrayListIterator[T]) Next() (T, error) {
	if !it.HasNext() {
		var zero T
		return zero, errors.New("没有下一个")
	}
	value, err := it.list.Get(it.currentIndex)
	it.currentIndex++
	return value, err
}

func (it *ArrayListIterator[T]) Remove() {
	it.currentIndex--
	it.list.Delete(it.currentIndex)
}

func (it *ArrayListIterator[T]) GetIndex() int {
	return it.currentIndex
}

迭代器中的方法,大多是使用我们在自定义数组中已经实现好的方法,所以写起来比较简单快捷

迭代器提供了一个统一的接口来遍历集合中的元素,而不必关心集合的具体实现细节。

2. 注意事项

  • 除了基础的顺序遍历方式,我们还可以自行定义其他遍历方式,例如:逆序遍历,从某个元素位置往后遍历 / 往前遍历,等等......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值