Golang1.18泛型_ArrayList

ArrayList

  • 与java的api基本保持一致,也可以使用泛型接口,但最新版的Goland的最新版本对泛型接口的支持有bug,编辑器会爆红,但代码可以正常运行

使用示例

func main() {
	p := &Person{
		Name: "java",
	}
	a := &Person{Name: "C++"}
	c := &Person{Name: "Golang"}

	list := ArrayList.New[Person]()
	list.Add(p)
	list.Add(a)
	list.Add(c)
	get := list.Get(0)
	array := list.ToArray()
	fmt.Println(get)
	fmt.Println(array)
	//var v *Person
	//a2 := insert[*Person](p)

	list.ForEach(func(o *Person) {

	})
	

	

}


type Person struct {
	Name string
}


接口使用示例

func main() {
	p := &Person{
		Name: "java",
	}
	a := &Person{Name: "C++"}
	c := &Person{Name: "Golang"}

	list := ArrayList.New[Person]()
	var l List[Person]
	l = list
	add := l.Add(p)
	l.Add(a)
	l.Add(c)
	fmt.Println(add)

	//list.Add(p)
	//list.Add(a)
	//list.Add(c)
	//get := list.Get(0)
	//array := list.ToArray()
	//fmt.Println(get)
	//fmt.Println(array)
	////var v *Person
	////a2 := insert[*Person](p)
	//
	//list.ForEach(func(o *Person) {
	//
	//})

}

type Person struct {
	Name string
}

//func (list *array[T]) Add(v *T) bool
type List[T any] interface {
	Add(*T) bool
}

源代码

package ArrayList

import (
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"
)

const defaultCap = 10

type array[T any] struct {
	elementData   []*T
	length        int
	size          int
	initalCapcity int
	dataType      string
	isAddAnyType  bool
	//foreach func(o *T)
}

// 只能填两个参数,第一个int用来规定ArrayList的容量,如果不填默认容量是10
//第二个bool规定List是否可以添加任意类型的数据,默认否
func New[T any](cap ...interface{}) *array[T] {
	if len(cap) > 2 {
		panic("argu too more ,less then 3")
	}

	//List = new()array[T]{
	//	isAddAnyType: false,
	//}
	List := &array[T]{}
	List.isAddAnyType = false

	if len(cap) == 0 {
		List.initalCapcity = defaultCap
		List.elementData = make([]*T, List.initalCapcity)
		List.length = List.initalCapcity
	} else if len(cap) == 1 {
		if cap[0].(int) > 0 {
			List.elementData = make([]*T, cap[0].(int))
			List.length = cap[0].(int)
		} else {
			panic("Illegal Capacity: " + strconv.FormatInt(int64(cap[0].(int)), 10))
		}

	} else if len(cap) == 2 {
		List.isAddAnyType = cap[1].(bool)
	}
	return List
}

func (list *array[T]) Size() int {
	return list.size
}

func (list *array[T]) IsEmpty() bool {
	return list.size == 0
}

//添加一个元素
func (list *array[T]) Add(v *T) bool {
	//fmt.Println(list.Size())
	list.add(v, list.elementData, list.Size())

	list.size++
	return true

}
func (list *array[T]) add(e *T, elementData []*T, s int) {
	var l = make([]*T, 0)
	l = elementData
	if s == list.length {
		l = append(l, e)
		list.length = len(l)
		list.elementData = l

	}
	list.elementData[s] = e

}
func (list *array[T]) grow(data []*T) {
	i := len(data)
	slice := make([]*T, i+i/4)

	copy(slice, data)
	list.length = len(slice)
	list.elementData = slice
}

func (list *array[T]) Get(index int) T {

	return *list.elementData[index]
}

//判断list是否含有v,如果有返回true,和索引
//如果没有返回false,-1
func (list *array[T]) Contains(object interface{}) (bool, int) {

	for i, v := range list.elementData {
		if equals(v, object) {
			return true, i
		}
	}
	return false, -1
}
func equals(a interface{}, b interface{}) bool {
	if e, ok := a.(compare); ok {
		return e.Equal(b)
	} else {
		return reflect.DeepEqual(a, b)
	}
}

type compare interface {
	Equal(object interface{}) bool
}

func (list *array[T]) RemoveByObject(o *T) bool {
	for i, v := range list.elementData {
		if equals(v, o) {
			list.delElm(o, i)
			return true
		}
	}
	return false
}
func (list *array[T]) RemoveByIndex(index int) {
	if index < 0 || index >= list.size {
		panic("index panic")
	}
	list.delElm(nil, index)
}
func (list *array[T]) delElm(o interface{}, index int) {
	dest := make([]*T, 0)
	dest = list.elementData[index:]
	src := list.elementData[index+1:]
	copy(dest, src)

	list.elementData[list.size-1] = nil

	list.size--

}

//批量添加一个数组
func (list *array[T]) AddArray(data []*T) {
	for i := 0; i < len(data); i++ {
		list.Add(data[i])
	}

}

func (list *array[T]) Clear() {
	for i := 0; i < list.size; i++ {
		list.elementData[i] = nil
	}
	list.size = 0
}

func (list *array[T]) ContainsAll(data []*T) bool {
	for i := 0; i < len(data); i++ {
		if b, _ := list.Contains(data[i]); b {

			continue
		} else {
			return false
		}
	}
	return true

}

func (list *array[T]) InsertByIndex(index int, o *T) {

	//arr := []int{0, 1, 2, 3, 4, 5, 6}
	//i := 100
	//index := 3
	//temp := arr[index:]
	//
	//arr = append(arr, 1)
	//front := arr[index+1:]
	//copy(front, temp)
	//arr[index] = i
	//fmt.Println(arr)
	temp := make([]*T, 0)
	temp = list.elementData[index:]
	l := make([]*T, 0)
	l = list.elementData
	list.elementData = append(l, o)
	front := list.elementData[index+1:]
	copy(front, temp)
	list.elementData[index] = o
	list.size++

}

func (list *array[T]) ForEach(f func(o *T)) {
	//list.foreach = f
	for i := 0; i < list.size; i++ {
		f(list.elementData[i])
	}

}
func (list *array[T]) Set(index int, o *T) {

	list.checkIndex(index)
	list.elementData[index] = o

}

func (list *array[T]) checkIndex(index int) {
	if index >= list.Size() || index < 0 {
		panic("index error , too big or less then 0")
	}
}

func (list *array[T]) Sort(x []*T, less func(i int, j int) bool) {
	if x == nil {
		panic("sort list nil error")
	}
	sort.Slice(list.ToArray(), less)
}

func (list *array[T]) ToArray() []T {
	res := make([]T, list.size)
	for i := 0; i < list.size; i++ {
		res[i] = *list.elementData[i]
	}
	return res
}

func (list *array[T]) String() string {
	var buf strings.Builder
	buf.WriteString("[ ")
	i := 0
	list.ForEach(func(o *T) {
		buf.WriteString(string(i))
		buf.WriteString(": ")
		sprintln := fmt.Sprintln(o)
		buf.WriteString(sprintln + " ")
		i++
	})
	buf.WriteString(" ]")
	return buf.String()

}

posted @ 2022-04-20 17:06  月下繁星杨  阅读(609)  评论(0编辑  收藏  举报